1. 程式人生 > >深入拆解虛擬機器(一)Java程式碼是咋樣執行的

深入拆解虛擬機器(一)Java程式碼是咋樣執行的

Java執行方式
序號 方式
1 開發工具中執行
2 雙擊Jar檔案執行
3 命令列中執行
4 網頁中執行
5 其他方式
為什麼Java要在虛擬機器中執行

(1)Java作為一門主流程式語言,語法非常複雜,抽象程度高。因此,直接在硬體上執行這種複雜程式並不現實,所以需要轉換

(2)轉換的主流思想:設計一個面向Java語言特性的虛擬機器,並通過編譯器將Java程式轉換成該虛擬機器所能識別的指令序列,也稱Java位元組碼


Java虛擬機器咋樣執行Java位元組碼
虛擬機器角度

(1)從虛擬機器角度來看,執行Java程式碼首先需要將它編譯成的class檔案載入到Java方法區中。載入後的Java類會被存放於方法區中。實際執行時,虛擬機器會執行方法區內的程式碼

(2)Java虛擬機器將棧細分為面向本地方法的本地方法棧,面向Java方法的Java方法棧以及存放各個執行緒執行位置的PC暫存器。

(3)在執行過程中,每當呼叫進入一個Java方法,Java虛擬機器會在當前執行緒的 Java方法棧中生成一個棧幀,用以存放區域性變數以及位元組碼的運算元。這個棧幀的大小是提前計算好的,而且Java虛擬機器不要求棧幀在記憶體空間裡連續分佈

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


硬體角度

(1)Java位元組碼無法直接執行,因此,Java虛擬機器需要將位元組碼翻譯成機器碼

(2)翻譯過程的兩種形式:第一種解釋執行,逐條將位元組碼翻譯成機器碼並執行;第二種及時編譯,即將一個方法中包含的所有位元組碼編譯成機器碼後執行

(3)前者的優勢在於無需等待編譯,後者的優勢在於實際執行速度更快。HotSpot預設採用混合模式。它會先解釋執行位元組碼,後將其中反覆執行的熱點程式碼,以方法為單位進行即時編譯

(4)為滿足不同使用者場景的需要,HotSpot內建多個即時編譯器:C1、C2和Graal。Graal是Java 10正式引入的實驗性即時編譯器

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

(6)C2又叫做Server編譯器,面向的是對峰值效能有要求的伺服器端程式,採用的優化手段相對複雜,因此編譯時間較長,但同時生成程式碼的執行效率較高

(7)從Java7開始,HotSpot預設採用分層編譯的方式:熱點程式碼首先被C1編譯,而後熱點方法中的熱點會進一步被C2編譯

(8)為了不干擾應用的正常執行,HotSpot的即時編譯放在額外的編譯執行緒中進行。HotSpot會根據CPU的數量設定編譯執行緒的數目,並且按照1:2的比例配置給C1及C2編譯器

(9)在計算機資源充足的情況下,位元組碼的解釋執行和即時編譯可同時進行。編譯完成後的機器碼會在下次呼叫該方法時啟動,以替代原本的解釋執行