Java虛擬機器(JVM)JIT優化


在本章中,我們將介紹JIT優化。

方法內聯

在這種優化技術中,編譯器決定用函式體替換函式呼叫。以下是實現相同功能的例子 -

int sum3;

static int add(int a, int b) {
   return a + b;
}

public static void main(String…args) {
   sum3 = add(5,7) + add(4,2);
}

//after method inlining
public static void main(String…args) {
   sum3 = 5+ 7 + 4 + 2;
}

使用這種技術,編譯器可以節省機器進行任何函式呼叫的開銷(它需要將引數推播和彈出到棧)。因此,生成的程式碼執行得更快。

方法內聯只能用於非虛擬函式(未被覆蓋的函式)。考慮如果add方法在子類中被覆蓋會發生什麼,並且在執行時之前不知道包含該方法的物件的型別。在這種情況下,編譯器不知道要內聯的方法。但是如果方法標記為final,那麼編譯器很容易知道它可以是內聯的,因為它不能被任何子類覆蓋。請注意,並不是都保證final方法始終是內聯的。

無法存取和死程式碼消除

無法存取的程式碼是任何可能的執行流都無法存取的程式碼。考慮以下範例 -

void foo() {
   if (a) return;
   else return;
   foobar(a,b); //unreachable code, compile time error
}

死程式碼也是無法存取的程式碼,但編譯器確實在這種情況下吐出錯誤。相反,只是得到一個警告。每個程式碼塊(例如建構函式,函式,trycatchifwhile等)都有自己的規則,用於在JLS(Java語言規範)中定義的無法存取的程式碼。

常數折疊

要了解常數摺疊概念,請參閱以下範例:

final int num = 5;
int b = num * 6; //compile-time constant, num never changes
//compiler would assign b a value of 30.