012Java虛擬機器004程式碼的執行
部分內容來自以下部落格:
https://www.cnblogs.com/old-cha/p/13324772.html
1 概述
先看一下Java虛擬機器的結構圖:
從圖中可以看到,當類載入器將class檔案的資料放到執行時資料區後,虛擬機器就使用執行引擎讀取程式碼並執行。
由於Java程式碼中有可能用到了本地化的方法,所以執行引擎還需要呼叫本地化方法庫中相應的本地化介面。
2 執行引擎
2.1 作用
執行引擎的任務就是將位元組碼指令解釋/編譯為對應平臺上的本地機器指令。
從外觀上看,所有的Java虛擬機器的執行引擎輸入、輸出都是一致的:輸入的是位元組碼的二進位制流,處理過程是位元組碼解析執行的等效過程,輸出的是執行結果。
2.2 分類
2.2.1 解釋和編譯
第一種是將原始碼編譯成位元組碼檔案,然後在執行時通過直譯器將位元組碼轉為機器碼執行
第二種是編譯執行(直接編譯成機器碼)。現代虛擬機器為了提高執行效率,會採用即時編譯技術(Just In Time)將方法編譯成機器碼後再執行。
2.2.2 兩者同時使用的原因
為什麼HotSpot中已經內建JIT(Just In Time Compiler)編譯器,還需要使用直譯器拖累程式效能?
1)當Java虛擬機器啟動時,直譯器可以先發揮作用,而不必等待即時編譯器全部編譯完成後再執行,這樣可以省去許多不必要的編譯時間。
2)隨著時間的推移,編譯器發揮作用,把越來越多的程式碼編譯成本地機器碼,獲得更高的執行效率。
3)同時,解釋執行在編譯期進行激進優化不成立時,作為後備方案。
2.3 直譯器
2.3.1 作用
當Java虛擬機器啟動時會對位元組碼採用逐行解釋的方式執行,將每條位元組碼檔案中的內容“翻譯”為對應平臺的本地機器指令執行。
當一條位元組碼指令被解釋執行完成後,接著再根據PC暫存器中記錄的下一條需要被執行的位元組碼指令執行解釋操作。
2.3.2 種類
在Java的發展歷史裡,一共有兩套解釋執行器,即古老的位元組碼直譯器、現在普遍使用的模板直譯器。
位元組碼直譯器在執行時通過純軟體程式碼模擬位元組碼的執行,效率非常低下。
模板直譯器將每一條位元組碼和一個模板函式關聯,模板函式中直接產生這條位元組碼執行時的機器碼,從而很大程度上提高了直譯器的效能。
2.3.3 組成
在HotSpot VM中,直譯器主要由Interceptor模組和Code模組構成。
Interceptor模組:實現瞭解釋器的核心功能。
Code模組:用於管理HotSpot VM在執行時生成的本地機器指令。
2.4 編譯器
2.4.1 作用
編譯器就是虛擬機器將原始碼直接編譯成本地機器平臺相關的機器語言。
2.4.2 即時編譯
即時編譯的目的是避免函式被解釋執行,而是將整個函式體編譯為機器碼,每次函式執行時,只執行編譯後的機器碼即可。
2.4.3 熱點程式碼
是否需要啟動JIT編譯器將位元組碼直接編譯為對應平臺的本地機器指令,需要根據程式碼被呼叫執行的頻率而定。
JIT編譯器在執行時會針對頻繁被呼叫的熱點程式碼進行深度優化,將其直接編譯為對應平臺的本地機器指令,從而提升Java程式的執行效能。
3 本地介面
JNI會與本地方法庫進行互動並提供執行引擎所需的本地庫。
4 本地方法庫
是一個執行引擎所需的本地庫的集合。