快來查看JVM不同組件的概述以及非常有用的圖表。
這是最近在國外論壇看到一個很實用的介紹,分享給大家哦。
每個Java開發(fā)人員都知道字節(jié)碼將由JRE(Java運行時環(huán)境)執(zhí)行。但是,許多人并不知道JRE是Java虛擬機(JVM)的實現(xiàn),它可以分析字節(jié)碼,解釋代碼并執(zhí)行它。作為開發(fā)人員,了解JVM的體系結(jié)構(gòu)非常重要,因為它使我們能夠更高效地編寫代碼。在本文中,我們將更深入地了解Java中的JVM體系結(jié)構(gòu)以及JVM的不同組件。
什么是JVM?
一個虛擬機是一個軟件實現(xiàn)物理機。Java是根據(jù)WORA(可在任何地方運行一次寫入)的概念開發(fā)的,該概念可在VM上運行。該編譯器編譯Java文件轉(zhuǎn)換成一個Java 的.class文件,則該.class文件輸入到JVM,它加載并執(zhí)行類文件。下圖是JVM的體系結(jié)構(gòu)圖。
JVM體系結(jié)構(gòu)圖
JVM如何工作?
如上面的架構(gòu)圖所示,JVM分為三個主要子系統(tǒng):
ClassLoader子系統(tǒng)
運行時數(shù)據(jù)區(qū)
執(zhí)行引擎
1. ClassLoader子系統(tǒng)
Java的動態(tài)類加載功能由ClassLoader子系統(tǒng)處理。它加載,鏈接。并在運行時(而非編譯時)首次引用類時初始化類文件。
1.1加載
類將由此組件加載。BootStrap ClassLoader,擴展ClassLoader和Application ClassLoader是有助于實現(xiàn)該目標(biāo)的三個ClassLoader。
BootStrap ClassLoader –負(fù)責(zé)從引導(dǎo)類路徑中加載類,僅用于rt.jar。最高優(yōu)先級將給予此加載程序。
擴展ClassLoader –負(fù)責(zé)加載ext文件夾(jre \ lib)內(nèi)的類。
Application ClassLoader –負(fù)責(zé)加載應(yīng)用程序級別的類路徑,提到的環(huán)境變量路徑等。
上面的ClassLoader在加載類文件時將遵循委托層次算法。
1.2連結(jié)
驗證 -字節(jié)碼驗證程序?qū)Ⅱ炞C生成的字節(jié)碼是否正確,如果驗證失敗,我們將收到驗證錯誤。
準(zhǔn)備 –將為所有靜態(tài)變量分配內(nèi)存并為其分配默認(rèn)值。
解決 –將所有符號內(nèi)存引用替換為“方法區(qū)域”中的原始引用。
1.3初始化
這是ClassLoading的最后階段;在此,所有靜態(tài)變量將被分配原始值,并且將執(zhí)行靜態(tài)塊。
2.運行時數(shù)據(jù)區(qū)
運行時數(shù)據(jù)區(qū)分為五個主要部分:
方法區(qū)域–所有類級別的數(shù)據(jù)(包括靜態(tài)變量)都將存儲在此處。每個JVM只有一個方法區(qū)域,它是共享資源。
堆區(qū)–所有對象及其對應(yīng)的實例變量和數(shù)組將存儲在此處。每個JVM還有一個堆區(qū)。由于“方法”和“堆”區(qū)域共享多個線程的內(nèi)存,因此存儲的數(shù)據(jù)不是線程安全的。
堆棧區(qū)–對于每個線程,將創(chuàng)建一個單獨的運行時堆棧。對于每個方法調(diào)用,將在堆棧存儲器中創(chuàng)建一個條目,稱為堆棧幀。所有局部變量都將在堆棧存儲器中創(chuàng)建。堆棧區(qū)域不是共享資源,因此是線程安全的。堆棧框架分為三個子實體:局部變量數(shù)組 –與該方法有關(guān),涉及多少局部變量,并且相應(yīng)的值將存儲在此處。操作數(shù)堆棧 –如果需要執(zhí)行任何中間操作,則操作數(shù)堆棧充當(dāng)執(zhí)行該操作的運行時工作區(qū)。幀數(shù)據(jù) –與該方法相對應(yīng)的所有符號都存儲在此處。在任何例外情況下,捕獲塊信息將保留在幀數(shù)據(jù)中。
PC寄存器 –每個線程將具有單獨的PC寄存器,以在執(zhí)行指令后保存當(dāng)前執(zhí)行指令的地址,PC寄存器將用下一條指令進(jìn)行更新。
本機方法堆棧 –本機方法堆棧保存本機方法信息。對于每個線程,將創(chuàng)建一個單獨的本機方法堆棧。
3.執(zhí)行引擎
分配給運行時數(shù)據(jù)區(qū)的字節(jié)碼將由執(zhí)行引擎執(zhí)行。執(zhí)行引擎讀取字節(jié)碼并逐段執(zhí)行。
解釋器–解釋器解釋字節(jié)碼的速度較快,但執(zhí)行速度較慢。解釋器的缺點是,當(dāng)多次調(diào)用一種方法時,每次都需要新的解釋。
JIT編譯器– JIT編譯器消除了解釋器的缺點。執(zhí)行引擎將使用解釋器的幫助來轉(zhuǎn)換字節(jié)碼,但是當(dāng)發(fā)現(xiàn)重復(fù)的代碼時,它將使用JIT編譯器,該編譯器將編譯整個字節(jié)碼并將其更改為本地代碼。此本地代碼將直接用于重復(fù)的方法調(diào)用,從而提高系統(tǒng)的性能。中間代碼生成器–產(chǎn)生中間代碼代碼優(yōu)化器–負(fù)責(zé)優(yōu)化上面生成的中間代碼目標(biāo)代碼生成器–負(fù)責(zé)生成機器代碼或本機代碼Profiler–一個特殊的組件,負(fù)責(zé)查找熱點,即是否多次調(diào)用該方法。
垃圾收集器:收集并刪除未引用的對象。垃圾回收可以通過調(diào)用觸發(fā)System.gc(),但不能保證執(zhí)行。JVM的垃圾收集收集創(chuàng)建的對象。
Java本機接口(JNI):JNI將與本機方法庫進(jìn)行交互,并提供執(zhí)行引擎所需的本機庫。
本機方法庫:這是本機庫的集合,這是執(zhí)行引擎所需的。
-
編譯器
+關(guān)注
關(guān)注
1文章
1634瀏覽量
49141 -
JVM
+關(guān)注
關(guān)注
0文章
158瀏覽量
12235
發(fā)布評論請先 登錄
相關(guān)推薦
評論