一次性聊透JVM架構設計,就算八股文也得會
有位小伙伴在我的粉絲群里面問我一個面試題,說面試被問對JVM的理解,不知道怎么回答,今天咱們來聊透,就算是八股文你也得會。另外,往期面試題解析中配套的文檔我已經準備好,想獲得的可以在文章底部加我\/領取!
先來看什么是JVM?
1.什么是JVM
JVM(Java Virtual Machine)其實是一套標準。通過定義虛擬機,像真實計算機一樣,能夠運行字節碼指令。JVM的好處是可以屏蔽操作系統的細節, 使Java可以一次編寫,到處運行。
實現JVM的廠商有很多,比如Hotspot、JRockit、IBM J9等等。今天我們重點來聊一聊主流的Hotspot,因為Oracle JDK與OpenJDK都是采用HotSpot VM。從源碼層面說,它們倆基本上沒什么區別。
2.JVM架構設計
下面我給大家詳細介紹一下JVM的架構設計,總體來看HotSpot VM 主要由3個核心部分組成:
- 類裝載子系統(Class Loader Subsystem)
- 運行時數據區(Runtime Data Areas)
- 執行引擎(Execution Engine)
那么Hotspot JVM架構細節和運行機制又是怎樣的呢?首先,將編譯好的.class文件裝載到類加載子系統,它的主要功能是查找并驗證類文件、完成相關內存空間的分配和對象賦值。
類文件加載到內存之后由運行時數據區來完成數據存儲和數據交換。運行時數據區又分為線程共享內存區和線程隔離內存區。線程共享內存區包括方法區和堆區,它們是程序員能夠通過編寫代碼直接操作的內存區,而線程隔離內存區包括棧區、程序計數器和本地方法棧,它們是完全由JVM來調度的內存區域。
首先來看方法區,它的主要功能是存儲運行時常量池、字段和方法的元數據和類的的元數據。
而堆區呢,主要是用來存儲Java對象的實例,也就是我們new的類都存在堆區。
棧區是通過線程的方式運行來加載各種方法。
程序計數器呢,是負責保存每個線程執行的方法的地址。
本地方法區是負責加載并運行native類型的方法,
這樣,通過運行時數據區的五個內存區就能完成Java程序程序邏輯的執行和數據交換。接下來看執行引擎,它主要包含即時編輯器和垃圾回收器。
即時編譯器,通俗地理解就是用來將字節碼翻譯成操作系統能夠執行的CPU指令,可以通過JVM參數來設置選擇解釋執行或者是編譯執行。
所謂解釋執行就是直接將字節碼作為源程序輸入解釋執行,不必等待編譯器全部編譯完成再執行,這樣可以省去許多不必要的編譯時間。
而編譯執行就是就是由編譯程序將目標代碼一次性編譯成目標程序,再由機器運行,執行效率更高,占用內存資源也更小
在Hotspot的實現中默認是兩種方式的組合。
垃圾回收器主要負責對運行時數據區的數據進行管理和回收,其實就是對各種垃圾回收算法的實現,總體來說有三種核心算法,分別是復制算法、標記清除算法和標記整理算法,這些算法的選擇呢,我們可以通過JVM參數來設置。
最后,來看本地方法接口,也就是JNI技術。我們可以通過JNI來查找并調用C或C++實現的代碼,還可以調用操作系統的動態鏈接庫(DLL)等等。
3、總結
好了,通過對Hotspot架構的分析,相信各位小伙伴已經非常清晰地知道了JVM的運行原理。當然,在實際的開發過程中,我們可以通過配置JVM參數來對JVM進行調優,比如這些參數。
還可以通過一些常見的JDK命令來分析JVM的狀態,查找問題的原因從而完成對JVM的調優,比如這些命令。