還記得上次被C開發人員嘲笑的時候嗎? Java如此繁瑣,以至于他們甚至都不會考慮使用這種語言?
在許多方面,這一概念仍然成立。 但是對于典型的用法(在大型企業的骨干中),Java性能絕對可以與許多競爭者抗衡。 這在很大程度上要歸功于神奇的JIT。
在深入解釋“即時”編譯技巧之前,讓我們深入了解一下背景知識。
您可能還記得– Java是一種解釋型語言。 大多數用戶都知道的Java編譯器javac不會像C編譯器那樣直接將Java源文件編譯為處理器指令。 而是生成字節碼,這是由規范控制的與機器無關的二進制格式。 JVM在運行時解釋該字節碼。這是Java在跨平臺上如此成功的主要原因-您可以在一個平臺上編寫和構建程序,然后在其他平臺上運行。 另一方面,它確實引入了一些負面方面。 其中最嚴重的事實之一是,解釋的代碼通常比直接編譯為平臺特定的本機二進制代碼的代碼要慢。 Sun雇用Cliff Click博士提供解決方案時,已經在90年代末意識到了這種嚴重性。
歡迎– HotSpot 。 該名稱源自JVM識別應用程序中“熱點”(經常執行的字節代碼塊)的功能。 然后將它們作為目標,以進行廣泛的優化并將其編譯為處理器專用指令。 通過優化,可以以最少的開銷實現對性能要求較低的代碼的高性能執行。 在某些情況下, JVM的自適應優化有可能超過手工編碼的C ++或C代碼的性能。
JVM中負責這些優化的組件稱為即時編譯器(JIT)。 它利用了有趣的程序屬性。 實際上,所有程序都將大部分時間都花在執行少量代碼上。 Java HotSpot VM不會及時編譯所有代碼,而是立即使用解釋器運行程序,并在運行時分析代碼以檢測程序中的關鍵熱點。 然后,它將全球本地代碼優化器的注意力集中在熱點上。 通過避免不經常執行的代碼的編譯,Java HotSpot編譯器可以更加關注程序的性能關鍵部分。 這意味著您的編譯時間總體上不會增加??。 該熱點監視將在程序運行時動態地繼續進行,以便根據您的應用程序的使用模式即時調整其性能。
JIT通過多種技術來實現性能優勢,例如消除無效代碼,繞過邊界條件檢查,消除冗余負載,內聯方法等。
以下示例說明了JIT用來實現更好性能的那些技術。 在第一部分中,有開發人員編寫的代碼。 在第二個代碼段中,是在熱點檢測到“熱點”并應用了優化魔術之后執行的代碼:
- 未優化的代碼。
class Calculator {Wrapper wrapper;public void calculate() {y = wrapper.get();z = wrapper.get();sum = y + z;} }class Wrapper {final int value;final int get() {return value;} }
- 優化代碼
class Calculator {Wrapper wrapper;public void calculate() {y = wrapper.value;sum = y + y;} }class Wrapper {final int value;final int get() {return value;} }
上面的小樣本中描述的第一類是開發人員編寫的類,第二類是JIT完成工作之后的示例。 該示例包含一些應用的優化技術。 讓我們看一下如何達到最終結果:
- 未優化的代碼。 這是在被檢測為熱點之前正在運行的代碼:
public void calculate() {y = wrapper.get();z = wrapper.get();sum = y + z; }
- 內聯方法。 wrapper.get()已被b.value取代,因為通過直接訪問wrapper.value而不是通過函數調用來減少延遲。
public void calculate() {y = wrapper.value;z = wrapper.value;sum = y + z; }
- 卸下多余的負載。 z = wrapper.value已替換為z = y,以便通過訪問局部值而不是wrapper.value來減少延遲。
public void calculate() {y = wrapper.value;z = y;sum = y + z; }
- 復制傳播。 z = y已由y = y代替,因為沒有多余的變量z,因為z和y的值相等。
public void calculate() {y = wrapper.value;y = y;sum = y + y; }
- 消除無效代碼。 y = y是不必要的,可以消除。
public void calculate() {y = wrapper.value;sum = y + y; }
這個小樣本包含JIT用來提高代碼性能的幾種強大技術。 希望它對理解這個強大的概念很有幫助。
喜歡這個職位嗎? 我們還有很多工作要做。 訂閱我們的RSS feed或Twitter流并享受。
本文使用了以下相關鏈接(兩個憤怒的C開發人員除外):
- http://www.oracle.com/technetwork/java/whitepaper-135217.html
- http://www.oracle.com/technetwork/java/javase/tech/index-jsp-136373.html
- http://docs.oracle.com/cd/E13150_01/jrockit_jvm/jrockit/geninfo/diagnos/underst_jit.html
參考: 您是否能及時編譯? 由我們的JCG合作伙伴 Nikita Salnikov Tarnovski在Plumbr Blog博客上獲得。
翻譯自: https://www.javacodegeeks.com/2012/12/do-you-get-just-in-time-compilation.html