這可能過於簡單了,但它會給你基本的想法。
這是一個測試類比較的方法有一個額外的參考和等效的方法與內聯調用:
public class Test {
static List<String> list = new ArrayList<>();
public static void extraReference() {
String s = new String();
list.add(s);
}
public static void noReference() {
list.add(new String());
}
}
下面是該方法的字節碼,以相同的順序,他們宣稱:
public static void extraReference();
Code:
0: new #2 // class java/lang/String
3: dup
4: invokespecial #3 // Method java/lang/String."<init>":()V
7: astore_0
8: getstatic #4 // Field list:Ljava/util/List;
11: aload_0
12: invokeinterface #5, 2 // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
17: pop
18: return
public static void noReference();
Code:
0: getstatic #4 // Field list:Ljava/util/List;
3: new #2 // class java/lang/String
6: dup
7: invokespecial #3 // Method java/lang/String."<init>":()V
10: invokeinterface #5, 2 // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
15: pop
16: return
如果你仔細看,只有區別是字節碼中的額外引用存儲/加載指令。
現在,如果此代碼是按原樣執行的,則可能會在很多調用之後發現差異 - 例如在循環中。額外的CPU週期可能會被燒燬,並且您必須在堆棧中使用一個位置來存儲引用(由於GC只處理堆,所以根本不應該打擾GC,並且堆棧中的項自動釋放this答案)。但我不會撥打成本顯着。
然而,實際上在每個JVM(以及Android使用的Dalvik VM,如果內存服務)上都存在被稱爲JIT編譯器的神奇實體。 JIT編譯器具有內嵌額外引用的能力,因此具有額外引用的代碼基本上與沒有額外引用的代碼完全相同。這應該是JIT編譯器執行相對容易的優化,特別是對於更現代的VM。
所以最後,如果有差異,你可以放心地忽略它由於JITC。在這種情況下,您應該選擇更易讀的代碼風格。
我不認爲這可以稱爲優化,但只是減少代碼。 –
我認爲你是對的。我看不出這會如何幫助內存使用。 'contact'在本地被定義在循環中,所以變量引用將被拋棄並且對象保持在兩種情況下。 – azurefrog
正如你所指出的,一個對象引用需要4或8個字節,但是你看今天的電子設備是微不足道的。在這種情況下,製作視頻的人不知道他在說什麼。 – awksp