在部分商用虛擬機中,Java程序最初是經過解釋器(Interpreter)進行解釋執行的,當虛擬機發現某個方法或者代碼塊的運行特別頻繁時,就會把這些代碼認定爲「熱點代碼」(Hot Spot Code)。爲提升熱點代碼的執行效率,在運行時,虛擬機將會把這些代碼編譯成與本地平臺相關的機器碼,並進行這種層次的優化,完成這個任務的編譯器成爲即時編譯器(Just In Time Compiler,簡稱JIT編譯器)。架構
Java虛擬機規範並無規定Java虛擬機必需要有即時編譯器存在。可是,即時編譯器編譯性能的好壞、代碼優化程度的高低確實衡量一款商用虛擬機優秀與否的關鍵指標之一,也是虛擬機中最核心且能體現虛擬機技術水平的部分。性能
HotSpot虛擬機內的即時編譯器優化
將要了解HotSpot虛擬機內即時編譯器的運做過程,同時,還要解決一下幾個問題:線程
爲什麼Hotspot虛擬機要使用解釋器與編譯器並存的架構?對象
爲什麼Hotspot虛擬機要實現兩個不一樣的即時編譯器?blog
程序什麼時候使用解釋器執行?什麼時候使用編譯器執行?繼承
那些程序代碼會被編譯爲本地代碼?如何編譯爲本地代碼?內存
如何從外部觀察即時編譯器的編譯過程和編譯結果?資源
解釋器與編譯器編譯器
解釋器與編譯器二者各有優點:當程序須要迅速啓動和執行的時候,解釋器能夠首先發揮做用,省去編譯的時間,當即執行。在程序運行後,隨着時間的推移,解釋器逐漸發揮做用,把愈來愈多的代碼編譯成本地代碼以後,能夠獲取更高的執行效率。當程序運行環境的內存資源有限制較大(如部分嵌入式系統),可使用解釋器執行節約內存,反之可使用編譯器執行來提高效率。同時,解釋器還能夠做爲編譯器激進優化時的一個「逃生門」,讓編譯器根據機率選擇一些大多數時都能提高運行速度的優化手段,當激進優化的假設不成立,如加載了新類後類型繼承結構出現變化、出現「罕見陷阱」(Uncommon Trap)時能夠經過逆優化(Deoptimization)退回到解釋狀態繼續執行,所以,整個虛擬機執行架構中,解釋器與編譯器常常配合工做。
Hotspot虛擬機中內置了兩個即時編譯器,分別爲Client Compiler和Server Compiler,或者簡稱C1編譯器和C2編譯器。目前主流的Hotspot虛擬機中,默認採用解釋器與其中一個編譯器直接配合的方式工做,程序使用那個編譯器,取決於虛擬機運行的模式,Hotspot虛擬機會根據自身版本與宿主機器的硬件性能自動選擇運行模式,用戶也可設置參數強制虛擬機使用的模式。
編譯器和解釋器搭配使用的方式成爲「混合模式」(Mixed Mode),用戶可設置參數強制虛擬機使用其中一種。
因爲即時編譯器編譯本地代碼須要佔用程序運行時間,要編譯出優化程度更高的代碼,所花費的時間可能更長;並且想要編譯出優化程度更高的代碼,解釋器可能還要替編譯器作收集性能監控信息,這對解釋執行的速度也有影響。爲了在程序啓動響應速度與運行效率之間達到最佳平衡,Hotspot虛擬機還會逐漸啓用分層編譯(Tiered Compilation)的策略。分層編譯根據編譯器編譯、優化的規模與耗時,劃分出不一樣編譯層次:
第0層,程序解釋執行,解釋器不開啓性能監控功能,可觸發第1層編譯。
第1層,也稱C1編譯,將字節碼編譯爲本地代碼,進行簡單、可靠的優化,若有必要將加入性能監控的邏輯。
第2層(或2層以上),也稱C2編譯,將字節碼編譯爲本地代碼,可是會啓用一些編譯耗時較長的優化,甚至會根據性能監控信息進行一些不可靠的激進優化。
實施分層編譯後,Client Compiler和Server Compiler將會同時工做,許多代碼均可能會被屢次編譯,用Client Compiler獲取更高的編譯速度,用Server Compiler來獲取更好的編譯執行,在解釋執行的時候也無須再承擔收集性能監控信息的任務。
編譯對象與觸發條件
在運行中被即時編譯器編譯的「熱點代碼」有兩類:
被屢次調用的方法。
被屢次執行的循環體。
判斷一段代碼是否是熱點代碼,是否是須要觸發即時編譯,這樣的行爲稱爲熱點探測(Hot Spot Detection),進行熱點探測並不必定要知道具體被調用了多少次,目前主要的熱點探測斷定方式有兩種:
基於採樣的熱點探測(Sample Based Hot Spot Detection):採用這種方法的虛擬機會週期性地檢查各個線程的棧頂,若是發現某個(或某些)方法常常出如今棧頂,那這個方法就是「熱點方法」。基於採樣的熱點探測的好處是實現簡單、高效,還能夠很容易地獲取方法調用關係(將調用堆棧展開便可),缺點是很難精確地確認一個方法的熱度,容易由於受到線程阻塞或別的外界因素的影響而擾亂熱點探測。
基於計數的熱點探測(Counter Based Hot Spot Detection):採用這種方法的虛擬機會爲每一個方法(甚至代碼塊)創建計數器,統計方法的執行次數,若是執行次數超過必定的閾值就認爲它是「熱點方法」。這種統計方法實現起來麻煩,須要爲每一個方法維護計數器,並且不能直接獲取到方法的調用關係,可是它的統計結果相對精確。
Hotspot虛擬機使用第二種。
編譯過程
查看及分析即便編譯結果
編譯優化技術