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