一、JVM體系結(jié)構(gòu)
JVM體系結(jié)構(gòu)分為4部分
? ? ? ? ? ? ? ? ? 類加載器、執(zhí)行引擎、內(nèi)存區(qū)、本地方法調(diào)用
1. 類加載器:在JVM啟動(dòng)時(shí),負(fù)責(zé)加載class文件到JVM中
? ? ? ? ? ? ? ? ? ? ? 類加載器將在分析Classloader中詳細(xì)介紹
2.執(zhí)行引擎:負(fù)責(zé)執(zhí)行class文件中的字節(jié)碼,相當(dāng)于計(jì)算機(jī)的cpu
? ? ? ? ? ? ? ? ? ? ?執(zhí)行引擎是JVM的核心部分,它負(fù)責(zé)解析JVM字節(jié)碼指令并得到執(zhí)行的結(jié)果,Java虛擬機(jī)規(guī)范中定義了遇到字節(jié)碼指令時(shí)應(yīng)該處理什么,并且應(yīng)該得到什么結(jié)果,但具體的執(zhí)行方式并沒有定義,而是由JVM廠家自己去實(shí)現(xiàn)。每
? ? ? ? ? ? ? ? ? ? ?執(zhí)行引擎就是執(zhí)行一條條代碼的一個(gè)流程,也就是執(zhí)行一個(gè)個(gè)java方法的流程。實(shí)際上,每個(gè)java線程就是一個(gè)執(zhí)行引擎的實(shí)例
3.內(nèi)存區(qū): 將內(nèi)存劃分成多個(gè)區(qū),模擬實(shí)際機(jī)器中的存儲(chǔ)、記錄、調(diào)度功能模塊
? ? ? ? ? ? ? ? ? ? ?在JVM執(zhí)行過(guò)程中需要保存一些信息,如操作碼的操作數(shù)、執(zhí)行的返回結(jié)果等,還有class類的字節(jié)碼等信息都要在JVM執(zhí)行前就準(zhǔn)備好。這些數(shù)據(jù)都是存儲(chǔ)在內(nèi)存區(qū)。
? ? ? ? ? ? ? ? ? ? ? JVM內(nèi)存區(qū)分為:方法、java堆、java棧、PC寄存器和本地方法區(qū)。方法去和java堆是線程共享的。而Java棧和PC寄存器是在每個(gè)執(zhí)行引擎實(shí)例(即線程)創(chuàng)建時(shí)單獨(dú)分配的,是線程間不共享的,java棧中保存的是方法的參數(shù)、變量、返回值等信息,PC寄存器是指向即將執(zhí)行的嚇一條指令的指針。
4.本地方法調(diào)用:調(diào)用C、C++實(shí)現(xiàn)的本地方法的代碼返回結(jié)果
二、JVM工作機(jī)制
1.JVM為何要基于棧的架構(gòu)
JVM執(zhí)行字節(jié)碼指令是基于棧的架構(gòu),所有操作數(shù)都要先入棧
理由:1、JVM要設(shè)計(jì)成與平臺(tái)無(wú)關(guān)的,即在有很少或沒有寄存器的機(jī)器上也能正常執(zhí)行
? ? ? ? ? ?2、為了指令的緊湊性。因?yàn)閖ava的字節(jié)碼有可能在網(wǎng)絡(luò)上傳輸,會(huì)節(jié)省空間
2.執(zhí)行引擎的架構(gòu)設(shè)計(jì)
每當(dāng)創(chuàng)建一個(gè)新線程時(shí),JVM會(huì)為這個(gè)線程創(chuàng)建一個(gè)Java棧和一個(gè)PC寄存器,并且寄存器會(huì)指向這個(gè)線程的第一行可執(zhí)行代碼。
每當(dāng)訪問(wèn)一個(gè)新方法時(shí),會(huì)在棧中創(chuàng)建一個(gè)新的棧幀數(shù)據(jù)結(jié)構(gòu),這個(gè)棧幀會(huì)保留這個(gè)方法的一些元信息。