JVM是什么
JVM全稱Java Virtual Machine(Java虛擬機(jī))仲智,是一個虛構(gòu)出來的計(jì)算機(jī)尝丐,它屏蔽了與具體操作系統(tǒng)平臺相關(guān)的信息绰筛,使得Java程序只需生成在Java虛擬機(jī)上運(yùn)行的目標(biāo)代碼(字節(jié)碼娇澎,ByteCode), 就可以在多種平臺上不加修改地運(yùn)行疲恢。這背后其實(shí)就是JVM把字節(jié)碼翻譯成具體平臺上的機(jī)器指令凶朗,從而實(shí)現(xiàn)“一次編寫,到處運(yùn)行(Write Once, Run Anywhere)”显拳。
JVM架構(gòu)圖
JVM工作機(jī)制
如上面的架構(gòu)圖所示棚愤,JVM分成四個主要的子系統(tǒng):
- 類加載器
- 運(yùn)行時數(shù)據(jù)區(qū)
- 執(zhí)行引擎
- 本地方法調(diào)用
類加載器
Java的動態(tài)類加載功能由類加載器子系統(tǒng)處理。它加載,鏈接宛畦,并在類運(yùn)行時第一次引用類時初始化類文件瘸洛,而不是編譯時。
1.1 加載
通過類加載器實(shí)現(xiàn)類的加載動作次和,絕大部分Java程序都會使用到以下三種系統(tǒng)提供的類加載器:
- 啟動類加載器(Bootstrap ClassLoader)
- 擴(kuò)展類加載器(Extension ClassLoader)
- 應(yīng)用程序類加載器(Application ClassLoader)
上面的類加載器將在加載類文件時遵循委托層次結(jié)構(gòu)算法反肋。
1.2 鏈接
- 驗(yàn)證 確保Class文件的字節(jié)流中包含的信息符合當(dāng)前虛擬機(jī)的要求,并且不會危害虛擬機(jī)自身的安全
- 準(zhǔn)備 正式為類變量分配內(nèi)存并設(shè)置初始值的階段踏施,這些變量所使用的內(nèi)存都將在方法區(qū)中進(jìn)行分配
- 解析 虛擬機(jī)將常量池內(nèi)的符號引用替換為直接引用的過程
1.3 初始化
這是類加載的最后階段石蔗,為所有的變量分配原始值,并執(zhí)行靜態(tài)代碼塊
運(yùn)行時數(shù)據(jù)區(qū)
Java虛擬機(jī)在運(yùn)行程序的過程中會把它所管理的內(nèi)存劃分為若干個不同的數(shù)據(jù)區(qū)畅形。這些區(qū)域都有各自的用途养距,以及創(chuàng)建和銷毀的時間,有的區(qū)域隨著虛擬機(jī)進(jìn)程的啟動而存在日熬,有的區(qū)域則依賴用戶線程的啟動和結(jié)束而建立和銷毀棍厌。
程序計(jì)數(shù)器
一塊較小的內(nèi)存空間,可以看作是當(dāng)前線程所執(zhí)行的字節(jié)碼行號指示器
Java虛擬機(jī)棧
Java虛擬機(jī)棧描述的是Java方法執(zhí)行的內(nèi)存模型竖席,每個方法在執(zhí)行的同時都會創(chuàng)建一個站幀(Stack Frame)用于存儲局部變量表耘纱、操作數(shù)棧、動態(tài)鏈接怕敬、方法出口等信息揣炕。每個方法從調(diào)用到執(zhí)行完成的過程,就對應(yīng)著一個棧幀在虛擬機(jī)棧中入棧到出棧的過程东跪。
本地方法棧
本地方法棧與虛擬機(jī)棧發(fā)揮的作用類似畸陡,虛擬機(jī)棧為虛擬機(jī)執(zhí)行Java方法(也就是字節(jié)碼)服務(wù)岭埠,而本地方法棧則為虛擬機(jī)使用的Native方法服務(wù)胸遇。
Java堆
Java堆是Java虛擬機(jī)所管理的內(nèi)存中最大的一塊崩掘。Java堆是被所有線程共享的一塊內(nèi)存區(qū)域欢搜,在虛擬機(jī)啟動時創(chuàng)建澜共。此內(nèi)存區(qū)域的唯一目的就是存放對象實(shí)例劝术,幾乎所有的對象實(shí)例都在這里分配內(nèi)存寥枝。
Java堆是垃圾收集器管理的主要區(qū)域井仰,因此很多時候也稱作GC堆恶守。
方法區(qū)
與Java堆一樣第献,是各個線程共享的內(nèi)存區(qū)域,它用于存儲已被虛擬機(jī)加載的類信息兔港、常量庸毫、靜態(tài)變量、即時編譯器編譯后的代碼等數(shù)據(jù)衫樊。
執(zhí)行引擎
執(zhí)行通過類加載器分配給運(yùn)行時數(shù)據(jù)區(qū)的字節(jié)碼飒赃,并將這些字節(jié)碼轉(zhuǎn)換成JVM虛擬機(jī)更容易執(zhí)行的語言利花。主要有三個子組件。
解釋器
負(fù)責(zé)讀取字節(jié)碼并順序的執(zhí)行载佳。缺點(diǎn)是當(dāng)一個方法被多次調(diào)用時炒事,每次都需要新的解釋。
JIT(Just In Time)編譯器
抵消了解釋器執(zhí)行緩慢的缺點(diǎn)蔫慧。JIT編譯器同時編譯字節(jié)碼的重復(fù)部分挠乳,總而減少編譯所需的總時間。從而提高性能藕漱。
- 中間代碼生成器 負(fù)責(zé)生成中間代碼
- 代碼優(yōu)化器 負(fù)責(zé)優(yōu)化上面生成的中間代碼
- 目標(biāo)代碼生成器 負(fù)責(zé)生成機(jī)器代碼或本機(jī)代碼
- Profiler 一個特殊組件欲侮,負(fù)責(zé)查找熱點(diǎn),即是否被多次調(diào)用
垃圾收集器
收集和刪除未引用的對象來釋放內(nèi)存肋联⊥叮可以通過調(diào)用觸發(fā)垃圾收集System.gc(),但不保證執(zhí)行橄仍。
本地方法接口
JNI與本地方法庫交互韧涨,并提供執(zhí)行引擎所需的本地庫
本地方法庫
執(zhí)行引擎所需要的本地庫的集合