Java虛擬機基本原理(一):Java代碼是怎麼運行的

1、運行方式

Java 代碼有很多種不同的運行方式。比如說可以在開發工具中運行,可以雙擊執行 jar 文件運行,也可以在命令行中運行,甚至可以在網頁中運行。當然,這些執行方式都離不開 JRE,也就是 Java 運行時環境。

2、JDK、JRE、JVM

JRE 僅包含運行 Java 程序的必需組件,包括 Java 虛擬機以及 Java 核心類庫等。我們 Java 程序員經常接觸到的 JDK(Java 開發工具包)同樣包含了 JRE,並且還附帶了一系列開發、診斷工具。

3、爲什麼Java要在虛擬機裏運行

Java 作爲一門高級程序語言,它的語法非常複雜,抽象程度也很高。因此,直接在硬件上運行這種複雜的程序並不現實。所以在運行 Java 程序之前,我們需要對其進行一番轉換

設計一個面向 Java 語言特性的虛擬機,並通過編譯器將 Java 程序轉換成該虛擬機所能識別的指令序列,也稱 Java 字節碼。Java 字節碼指令的操作碼(opcode)被固定爲一個字節(起名原因)。

Java 虛擬機可以由硬件實現 ,但更爲常見的是在各個現有平臺(如 Windows_x64、Linux)上提供軟件實現。一旦一個程序被轉換成 Java 字節碼,那麼它便可以在不同平臺上的虛擬機實現裏運行。這也就是我們經常說的“一次編寫,到處運行”(可移植性)。

虛擬機的另外一個好處是它帶來了一個託管環境(Managed Runtime)。這個託管環境能夠代替我們處理一些代碼中冗長而且容易出錯的部分。其中最廣爲人知的當屬自動內存管理與垃圾回收,這部分內容甚至催生了一波垃圾回收調優的業務。

除此之外,託管環境還提供了諸如數組越界、動態類型、安全權限等等的動態檢測,使我們免於書寫這些無關業務邏輯的代碼。

4、Java虛擬機如何運行Java字節碼

從虛擬機視角來看,執行 Java 代碼首先需要將它編譯而成的 class 文件加載到 Java 虛擬機中。加載後的 Java 類會被存放於方法區(Method Area)中。實際運行時,虛擬機會執行方法區內的代碼。

在運行過程中,每當調用進入一個 Java 方法,Java 虛擬機會在當前線程的 Java 方法棧中生成一個棧幀,用以存放局部變量以及字節碼的操作數。這個棧幀的大小是提前計算好的,而且 Java 虛擬機不要求棧幀在內存空間裏連續分佈。

當退出當前執行的方法時,不管是正常返回還是異常返回,Java 虛擬機均會彈出當前線程的當前棧幀,並將之捨棄。

從硬件視角來看,Java 字節碼無法直接執行。因此,Java 虛擬機需要將字節碼翻譯成機器碼。

在 HotSpot 裏面,上述翻譯過程有兩種形式:第一種是解釋執行,即逐條將字節碼翻譯成機器碼並執行;第二種是即時編譯(Just-In-Time compilation,JIT),即將一個方法中包含的所有字節碼編譯成機器碼後再執行。

前者的優勢在於無需等待編譯,而後者的優勢在於實際運行速度更快。HotSpot 默認採用混合模式,綜合瞭解釋執行和即時編譯兩者的優點。它會先解釋執行字節碼,而後將其中反覆執行的熱點代碼,以方法爲單位進行即時編譯。

5、Java虛擬機的運行效率

HotSpot 採用了多種技術來提升啓動性能以及峯值性能,剛剛提到的即時編譯便是其中最重要的技術之一。

即時編譯建立在程序符合二八定律的假設上,也就是百分之二十的代碼佔據了百分之八十的計算資源。

對於佔據大部分的不常用的代碼,我們無需耗費時間將其編譯成機器碼,而是採取解釋執行的方式運行;另一方面,對於僅佔據小部分的熱點代碼,我們則可以將其編譯成機器碼,以達到理想的運行速度。

爲了滿足不同用戶場景的需要,HotSpot 內置了多個即時編譯器:C1、C2 和 Graal。

之所以引入多個即時編譯器,是爲了在編譯時間和生成代碼的執行效率之間進行取捨。C1 又叫做 Client 編譯器,面向的是對啓動性能有要求的客戶端 GUI 程序,採用的優化手段相對簡單,因此編譯時間較短。

C2 又叫做 Server 編譯器,面向的是對峯值性能有要求的服務器端程序,採用的優化手段相對複雜,因此編譯時間較長,但同時生成代碼的執行效率較高。

從 Java 7 開始,HotSpot 默認採用分層編譯的方式:熱點方法首先會被 C1 編譯,而後熱點方法中的熱點會進一步被 C2 編譯。

爲了不干擾應用的正常運行,HotSpot 的即時編譯是放在額外的編譯線程中進行的。HotSpot 會根據 CPU 的數量設置編譯線程的數目,並且按 1:2 的比例配置給 C1 及 C2 編譯器。

在計算資源充足的情況下,字節碼的解釋執行和即時編譯可同時進行。編譯完成後的機器碼會在下次調用該方法時啓用,以替換原本的解釋執行。

Ps:此係列文章來自於對極客時間的《深入拆解Java虛擬機》的閱讀筆記,總結溫習之用

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章