Java虛擬機如何運行Java字節(jié)碼
Java虛擬機如何運行Java字節(jié)碼
以標(biāo)準(zhǔn) JDK 中的 HotSpot 虛擬機為例,從虛擬機以及底層硬件兩個角度來看Java 虛擬機具體是怎么運行 Java 字節(jié)碼的。
虛擬機視角
從虛擬機視角來看,執(zhí)行 Java 代碼首先需要將它編譯而成的 class 文件加載到 Java 虛擬機中。
加載后的 Java 類會被存放于方法區(qū)(Method Area)中。
實際運行時,虛擬機會執(zhí)行方法區(qū)內(nèi)的代碼。

在運行過程中,每當(dāng)調(diào)用進入一個 Java 方法,Java 虛擬機會在當(dāng)前線程的 Java 方法棧中生成一個棧幀,用以存放局部變量以及字節(jié)碼的操作數(shù)。
這個棧幀的大小是提前計算好的,而且 Java 虛擬機不要求棧幀在內(nèi)存空間里連續(xù)分布。
當(dāng)退出當(dāng)前執(zhí)行的方法時,不管是正常返回還是異常返回,Java 虛擬機均會彈出當(dāng)前線程的當(dāng)前棧幀,并將之舍棄。
硬件視角
從硬件視角來看,Java 字節(jié)碼無法直接執(zhí)行。因此,Java 虛擬機需要將字節(jié)碼翻譯成機器碼。
在 HotSpot 里面,上述翻譯過程有兩種形式:
- 第一種是解釋執(zhí)行,即逐條將字節(jié)碼翻譯成機器碼并執(zhí)行;
- 第二種是即時編譯(Just-In-Time compilation,JIT),即將一個方法中包含的所有字節(jié)碼編譯成機器碼后再執(zhí)行。
前者的優(yōu)勢在于無需等待編譯,而后者的優(yōu)勢在于實際運行速度更快。

HotSpot 默認采用混合模式,綜合了解釋執(zhí)行和即時編譯兩者的優(yōu)點。
它會先解釋執(zhí)行字節(jié)碼,而后將其中反復(fù)執(zhí)行的熱點代碼,以方法為單位進行即時編譯。
即時編譯
即時編譯建立在程序符合二八定律的假設(shè)上,也就是百分之二十的代碼占據(jù)了百分之八十的計算資源。
對于占據(jù)大部分的不常用的代碼,我們無需耗費時間將其編譯成機器碼,而是采取解釋執(zhí)行的方式運行;
另一方面,對于僅占據(jù)小部分的熱點代碼,我們則可以將其編譯成機器碼,以達到理想的運行速度。
為了滿足不同用戶場景的需要,HotSpot 內(nèi)置了多個即時編譯器:C1、C2 和 Graal。
Graal 是 Java 10 正式引入的實驗性即時編譯器,這里暫不做討論。
之所以引入多個即時編譯器,是為了在編譯時間和生成代碼的執(zhí)行效率之間進行取舍。
- C1 又叫做 Client 編譯器,面向的是對啟動性能有要求的客戶端 GUI 程序,采用的優(yōu)化手段相對簡單,因此編譯時間較短。
- C2 又叫做 Server 編譯器,面向的是對峰值性能有要求的服務(wù)器端程序,采用的優(yōu)化手段相對復(fù)雜。
因此編譯時間較長,但同時生成代碼的執(zhí)行效率較高。
從 Java 7 開始,HotSpot 默認采用分層編譯的方式:熱點方法首先會被 C1 編譯,而后熱點方法中的熱點會進一步被 C2 編譯。
為了不干擾應(yīng)用的正常運行,HotSpot 的即時編譯是放在額外的編譯線程中進行的。
HotSpot 會根據(jù) CPU 的數(shù)量設(shè)置編譯線程的數(shù)目,并且按 1:2 的比例配置給 C1 及 C2 編譯器。
在計算資源充足的情況下,字節(jié)碼的解釋執(zhí)行和即時編譯可同時進行。
編譯完成后的機器碼會在下次調(diào)用該方法時啟用,以替換原本的解釋執(zhí)行。
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
如何利用SpringBoot搭建WebService服務(wù)接口
之前項目經(jīng)理想要開發(fā)一個webservice的協(xié)議,給我一個星期的時間,后面用springboot開發(fā)了webservice,這篇文章主要給大家介紹了關(guān)于如何利用SpringBoot搭建WebService服務(wù)接口的相關(guān)資料,需要的朋友可以參考下2023-11-11
詳解Java中多線程異常捕獲Runnable的實現(xiàn)
這篇文章主要介紹了詳解Java中多線程異常捕獲Runnable的實現(xiàn)的相關(guān)資料,希望通過本文能幫助到大家,讓大家理解掌握這樣的知識,需要的朋友可以參考下2017-10-10
SpringBoot超詳細講解@Enable*注解和@Import
這篇文章主要介紹了SpringBoot?@Enable*注解和@Import,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-07-07

