在本章中,我們將介紹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
}
死程式碼也是無法存取的程式碼,但編譯器確實在這種情況下吐出錯誤。相反,只是得到一個警告。每個程式碼塊(例如建構函式,函式,try
,catch
,if
,while
等)都有自己的規則,用於在JLS(Java語言規範)中定義的無法存取的程式碼。
常數折疊
要了解常數摺疊概念,請參閱以下範例:
final int num = 5;
int b = num * 6; //compile-time constant, num never changes
//compiler would assign b a value of 30.