2013-10-09 45 views
4

在Java中,如果我有很多本地對象,如果將它們定義爲實例變量,它會運行得更快嗎?例如,如果我的func1()被多次調用,例如在一個循環中,那麼每次調用該函數時,JVM會不會實例化並垃圾收集list2?我應該重複使用相同的list1對象來防止垃圾收集和實例化開銷?Java優化:本地變量與實例變量

class A { 
    List list1 = new ArrayList(); 
    private void func1() { 
     list1.clear(); 
     // add new objects list1 

     List list2 = new ArrayList(); 
     // add new objects to list2 
    } 
} 

優化器是否足夠智能以跳過垃圾回收並自動重用該對象?

+4

'Optimization.PREMATURE == Math.sqrt(EvilUtils.getAll(Evil.class))'求值真的......你確定這個問題給你帶來了問題,還是僅僅是一個過早優化的情況?它聞起來像是我的第二個案例... – ppeterka

+0

只是好奇心。想要了解當我需要坐下來優化我的代碼時可用的選項。 – JavaMan

回答

1

我寫了JDK1.6一個小的測試程序,下面

結果:
*爲dostuff 594ms(即創建本地)
* dmsuff2(使用實例)爲58ms

public class Test { 

static long counter=0; 
public static void main(String[] args) { 
    long t1 = System.nanoTime(); 
    Test test = new Test(); 
    for (int i=0;i<1000000000;i++) { 
     test.doStuff();//or dostuff2 
    } 
    long t2 = System.nanoTime(); 
    System.err.println((t2-t1)/1000000); 
    System.err.println(counter); // to check it wasnt optimised away 
} 

private void doStuff() { 
    List l = new ArrayList(); 
    if (l!=null) { 
     counter++; 
    } 
} 

List l2 = new ArrayList(); 
private void doStuff2() { 
    if (l2!=null) { 
     counter++; 
    } 
} 
} 

結果,似乎實例比使用本地,正如人們所預料得更快。

但是,看起來你節省了大約0。每十億的項目5秒,在我的電腦至少,所以你需要真的需要PERF增益,以證明它

2

GC優化不是正確的方法來決定Local vs Instance變量。如果一個變量需要被多個實例方法使用,那麼使用一個實例變量是有意義的。

你說得對,局部變量的使用可能會增加GC活動。

1

在決定是使用本地變量還是實例變量之前,可能需要考慮各種用例。性能可能因用例而異。

一個很好的例子可以在Effective Java發現:Item 5 - 「避免創建不必要的對象

+0

+1環節都有很好的解釋 – SpringLearner

1

想想也是實例變量值的線程安全。同一對象的兩個線程需要同步對實例變量數據的訪問,但這裏始終是一個新的局部變量數據對象。

1

如果 - 且僅當 - 你已經證明你有,因爲創建對象的GC的問題,你應該考慮池是證明要創建昂貴的對象。

對於這一點,你不必重新發明輪子的任何,您可以用FastList.newInstance()呼叫使用Javolutions utils的,FastList在這種情況下,實現這一目標,例如:

List<Whatever> newOrReusedList = FastList.newInstance(); 

...和相應的FastList.recycle(FastList)調用以使其可用於重用。 (感謝@JIV,我忘了補充該位。)

(要小心的是,使用javolutions快速*類可能會導致不同的表現:他們正朝着可預見的性能(實時系統減速),而不是速度,所以可能是使用的情況下,當他們比他們的同行java.lnag執行速度較慢)

+0

但你也需要釋放你不後需要手動他們 – JIV

+0

@JIV感謝所有未使用的高速郵件,我忘了補充一點。 – ppeterka