簡體   English   中英

Java優化:局部變量與實例變量

[英]Java Optimization: Local Variable Vs Instance Variable

在Java中,如果我有很多本地對象,如果我將它們定義為實例變量,它會運行得更快嗎? 例如,如果多次調用我的func1(),比如在循環中調用,那么每次調用函數時,JVM是否會繼續實例化並垃圾收集list2? 相反,我應該重用相同的list1對象來防止垃圾收集和實例化開銷嗎?

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

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

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

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

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

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

Effective Java中可以找到一個很好的例子: 第5項 - “ 避免創建不必要的對象

還要考慮實例變量值的線程安全性。 同一對象的兩個線程需要同步訪問實例變量數據,但在這里它始終是一個新的局部變量數據對象。

如果 - 並且僅當 - 您已經證明由於對象創建而導致GC出現問題,您應該考慮合並已證明成本高昂的對象。

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

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

...以及相應的FastList.recycle(FastList)調用,以使其可供重用。 (謝謝@JIV ,我忘了添加這一點。)

(請注意,使用javolutions Fast *類可能會導致不同的性能:它們面向可預測的性能(實時系統)而不是速度,因此可能存在用例,當它們的執行速度比java.lnag的速度慢時)

我用下面的jdk1.6寫了一個小測試程序

結果:
* dostuff為594ms(創建本地)
* dostuff2的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億美元的物品,所以你需要真的需要性能增益來證明它的合理性。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM