《深入理解Java虛擬機器》:HotSpot虛擬機器內的即時編譯器

來源:互聯網
上載者:User

標籤:java虛擬機器   jit   即時編譯器   

HotSpot虛擬機器內的即時編譯器

最近在看周志明老師的《深入理解Java虛擬機器》這本書,看了之後感覺收穫挺多的,於是就寫點讀書總結吧。

先看如下問題:

  • 1、 為何HotSpot虛擬機器要使用解譯器與編譯器並存的架構?
  • 2、 為何HotSpot虛擬機器要實現兩個不同的即時編譯器?
  • 3、 程式何時使用解譯器執行?何時使用編譯器執行?
  • 4、 那些程式碼會被編譯為本地代碼?如何便以為本地代碼?

Java程式最初是僅僅通過解譯器解釋執行的,即對位元組碼逐條解釋執行,這種方式的執行速度相對會比較慢,尤其當某個方法或代碼塊啟動並執行特別頻繁時,這種方式的執行效率就顯得很低。於是後來在虛擬機器中引入了JIT編譯器(即時編譯器),當虛擬機器發現某個方法或代碼塊運行特別頻繁時,就會把這些代碼認定為“Hot Spot Code”(熱點代碼),為了提高熱點代碼的執行效率,在運行時,虛擬機器將會把這些代碼編譯成與本地平台相關的機器碼,並進行各層次的最佳化,完成這項任務的正是JIT編譯器。

下面以問答的形式進行敘述

  • 1、為什麼HotSpot虛擬機器要使用解譯器與編譯器並存的架構??

現在主流的商用虛擬機器(如Sun HotSpot、IBM J9)中幾乎都同時包含解譯器和編譯器(三大商用虛擬機器之一的JRockit是個例外,它內部沒有解譯器,因此會有啟動相應時間長之類的缺點,但它主要是面向服務端的應用,這類應用一般不會重點關注啟動時間)。二者各有優勢:當程式需要迅速啟動和執行時,解譯器可以首先發揮作用,省去編譯的時間,立即執行;當程式運行後,隨著時間的推移,編譯器逐漸會發揮作用,把越來越多的代碼編譯成本地代碼後,可以擷取更高的執行效率。解釋執行可以節約記憶體,而編譯執行可以提升效率。在整個虛擬機器執行架構中,解譯器與編譯器經常配合工作。

  • 2、為什麼HotSpot虛擬機器要實現兩個不同的即時編譯器的原因???

HotSpot虛擬機器中內建了兩個即時編譯器:Client Complier和Server Complier,簡稱為C1、C2編譯器,分別用在用戶端和服務端,目前主流的HotSpot虛擬機器中預設是採用解譯器與其中一個編譯器直接配合的方式工作。程式使用哪個編譯器,取決於虛擬機器啟動並執行模式。HotSpot虛擬機器會根據自身版本與宿主及其的硬體效能自動選擇運行模式,使用者也可以使用“-client”或“-server”參數去強制指定虛擬機器運行在Client模式或Server模式。用Client Complier擷取更高的編譯速度,用Server Complier 來擷取更好的編譯品質

  • 4、 那些程式碼會被編譯為本地代碼?如何編譯為本地代碼?

程式中的代碼只有是熱點代碼時,才會編譯為本地代碼,那麼什麼是熱點代碼呢?

運行過程中會被即時編譯器編譯的“熱點代碼”有兩類

  • 被多次調用的方法。
  • 被多次調用的迴圈體。

兩種情況,編譯器都是以整個方法作為編譯對象,這種編譯也是虛擬機器中標準的編譯方式。
如何判斷方法或一段代碼或是不是熱點代碼呢
要知道方法或一段代碼是不是熱點代碼,是不是需要觸發即時編譯,需要進行Hot Spot Detection(熱點探測)。目前主要的熱點 判定方式有以下兩種:

(1)基於採樣的熱點探測

採用這種方法的虛擬機器會周期性地檢查各個線程的棧頂,如果發現某些方法經常出現在棧頂,那這段方法代碼就是“熱點代碼”。這種探測方法的好處是實現簡單高效,還可以很容易地擷取方法調用關係,缺點是很難精確地確認一個方法的熱度,容易因為受到線程阻塞或別的外界因素的影響而擾亂熱點探測。

(2)基於計數器的熱點探測

採用這種方法的虛擬機器會為每個方法,甚至是代碼塊建立計數器,統計方法的執行次數,如果執行次數超過一定的閥值,就認為它是“熱點方法”。這種統計方法實現複雜一些,需要為每個方法建立並維護計數器,而且不能直接擷取到方法的調用關係,但是它的統計結果相對更加精確嚴謹。

HotSpot虛擬機器中使用的是哪鐘熱點檢測方式呢

在HotSpot虛擬機器中使用的是第二種——基於計數器的熱點探測方法,因此它為每個方法準備了兩個計數器:方法調用計數器和回邊計數器。在確定虛擬機器運行參數的前提下,這兩個計數器都有一個確定的閾值,當計數器超過閾值溢出了,就會觸發JIT編譯。

方法調用計數器:這個計數器用於統計方法被調用的次數。

  • 3、 程式何時使用解譯器執行?何時使用編譯器執行?

當一個方法被調用時,會先檢查該方法是否存在被JIT編譯過的版本,如果存在,則優先使用編譯後的本地代碼來執行。如果不存在已被編譯過的版本,則將此方法的調用計數器值加1,然後半段方法調用計數器與回邊計數器值之後是否超過方法調用計數器的閾值。如果超過閾值,那麼將會想即時編譯器提交一個該方法的代碼編譯請求。

如果不做任何設定,執行引擎並不會同步等待編譯請求完成,而是繼續進行解譯器按照解釋方式執行位元組碼,直到提交的請求被編譯器編譯完成。當編譯工作完成之後,這個方法的調用入口地址就會系統自動改寫成新的,下一次調用該方法時就會使用已編譯的版本。

回邊計數器:統計一個方法中迴圈體代碼執行的次數。應用與迴圈體的回邊計數器與方法計數器的原理一樣,這裡就不在敘述。

著作權聲明:本文為博主原創文章,未經博主允許不得轉載。

《深入理解Java虛擬機器》:HotSpot虛擬機器內的即時編譯器

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.