1. 程式人生 > >晚期(執行期)優化——HotSpot虛擬機器內的即時編譯器

晚期(執行期)優化——HotSpot虛擬機器內的即時編譯器

文章目錄


首先,我們要知道以下概念
熱點程式碼

就是會執行特別頻繁的程式碼,會被編譯成機器碼。

將熱點程式碼編譯成機器碼這個任務是由**即時編譯器(後臺執行期編譯器)**完成的。

還有注意一點,即時編譯器並不是必須的,但是衡量一款商用虛擬機器優秀與否最關鍵的指標之一。

這一節,我們要完成以下幾個問題:

  • 1.何Hotspot虛擬機器要使用直譯器和編譯器並存的架構?
  • 2.為什麼Hotspot實現了兩個不同的即時編譯器(C1、C2)
  • 3.程式什麼時候使用直譯器執行?什麼時候使用編譯器執行?
  • 4.哪些程式碼(熱點程式碼)會被編譯成原生代碼?如何編譯成原生代碼?
  • 5.如何從外部觀察即時編譯器的編譯過程和編譯結果?

最後,需要注意一點:這一節指的編譯器都是Hotspot的即時編譯器,虛擬機器也指HotSpot虛擬機器


一、直譯器與編譯器

1.1 直譯器與編譯器的優勢

對於問題1,我們就要說一下直譯器和編譯器各自的優點了。

  • 如果想快速啟動和執行,直譯器就很不錯。但是隨著時間的推移,使用編譯器會獲得更高的執行效率
  • 如果記憶體資源限制比較大,可以使用直譯器節約記憶體。反之可以使用編譯執行類提高執行效率
  • 直譯器還可以充當編譯器激進優化的逃生門。當激進優化發生問題時,可以通過逆優化退回到解釋狀態繼續執行。

直譯器和編譯器的互動:

1.2 C1與C2

C1:Client Compiler
C2:Server Compiler
可以通過“-client”與“-server”引數去強制指定虛擬機器執行在Client模式或Server模式。

1.3 混合模式、解釋模式、編譯模式

混合模式:直譯器和編譯器混合使用的模式
解釋模式:全部程式碼使用解釋方式執行,編譯器不介入工作
編譯模式:嘗試讓全部程式碼在編譯方式下執行,實在不行,還是要採用解釋方式執行

可以設定“-Xint”或“Xcomp”讓編譯器執行在解釋模式或編譯模式。

1.4 分層編譯

為了在程式啟動響應速度與執行效率之間達到最佳平衡,Hotspot虛擬機器會逐漸啟用分層編譯的策略。對應問題2。

第i層 任務
0 程式解釋執行,不開啟效能監控功能,可出發第1層編譯
1 也稱為C1編譯,將位元組碼編譯為原生代碼,進行簡單、可靠的優化,如有必要將加入效能監控的邏輯
2 也稱C2編譯,也將位元組碼編譯為原生代碼,但會開啟一些編譯耗時比較長的優化,甚至會根據效能監控資訊進行一些不可靠的激進優化

二、編譯物件與出發條件

2.1 熱點程式碼

對於問題3,4,什麼時候進行解釋執行,什麼時候進行編譯執行?熱點程式碼就編譯執行唄!熱點程式碼有兩類:

型別 編譯物件
被多次呼叫的方法 編譯物件就是整個方法
被多次執行的迴圈體 編譯物件還是整個方法。雖然編譯動作是有迴圈體觸發的。這種編譯方式是發生在方法執行過程中的,形象的稱為棧上替換,即OSR

2.2 熱點探測

熱點探測,用於判斷一段程式碼是否為熱點程式碼。目前主要的熱點探測技術有兩種:

種類 說明
基於取樣的熱點探測 如果一個方法經常出現線上程的棧頂,那麼它就是熱點程式碼。但是,這種方式回受到執行緒阻塞的影響,進而得到非正常結果
基於計數器的熱點探測 為每個方法,甚至程式碼塊建立計數器,統計執行次數,當執行次數超過一定閾值就為熱點程式碼。

2.3 HotSpot的基於計數器的熱點探測方法

HotSpot為方法提供了兩類計數器——方法呼叫計數器(統計方法呼叫次數)、回邊計數器(統計方法中迴圈體執行的次數)。下面的計數器觸發編譯都是C1的,C2要複雜一些。
(1)方法呼叫計數器出發編譯

需要注意的是,當超過一定的時間限度,如果方法的呼叫次數仍然不超過閾值,那麼這個方法的呼叫計數器就會被減半,這就是方法的——半衰期

(2)回邊計數器出發即時編譯(疑問:編譯物件是方法,而迴圈體的上一次執行應該儲存下來,以便下一次執行時,在機器碼中(方法)找到迴圈體的狀態)

注意:”調整回邊計數器值,稍微降低一些,以便解釋執行能夠繼續“這一步是要等待編譯器輸出編譯結果的


三、編譯過程

C1、C2的編譯過程不一樣。
(1)C1的編譯過程——簡單快速的三段式編譯器

階段 說明 平臺相關
第一階段 將位元組碼轉換為高階中間程式碼 平臺獨立
第二階段 從高階中間程式碼轉換為低階中間程式碼 平臺相關
第三階段 使用線性掃描演算法優化產生機器程式碼 平臺相關

(2)C2的編譯過程
C2相對於C1,程式碼質量提高了,可以減少原生代碼的執行時間,從而抵消編譯時間。所以也有些非服務端的應用選擇使用C2模式的虛擬機器執行。

四、檢視及分析即時編譯結果

後面有時間在寫!!!

參考文獻

周志明的《深入理解java虛擬機器JVM高階特性與最佳實踐》