JVM体系结构:JVM类加载器和运行时数据区
各位讀者好! 在JVM系列的上一篇文章中,開發(fā)人員了解了Java虛擬機(JVM)及其體系結(jié)構(gòu)。 本教程將幫助開發(fā)人員正確回答以下主題的問題:
- ClassLoader子系統(tǒng)
- 運行時數(shù)據(jù)區(qū)
1.簡介
在繼續(xù)之前,讓我們看一下Java虛擬機及其基本特征。
1.1什么是Java虛擬機(JVM)?
Java虛擬機(JVM)是??駐留在您的計算機上的抽象虛擬機,并為Java字節(jié)碼提供了運行時環(huán)境以供執(zhí)行。 JVM可用于許多硬件和軟件平臺,但是很少有Java開發(fā)人員知道Java運行時環(huán)境 (JRE)是Java虛擬機 (JVM)的實現(xiàn)。 JVM分析字節(jié)碼,對其進行解釋,然后執(zhí)行相同的字節(jié)碼以顯示輸出。
JVM的基本功能是執(zhí)行已編譯的.class文件(即字節(jié)碼)并生成輸出。 請注意 ,每個操作系統(tǒng)都有一個不同的JVM,但是在所有操作系統(tǒng)上生成的字節(jié)碼輸出都是相同的。 這意味著在Windows操作系統(tǒng)上生成的字節(jié)碼也可以在Linux操作系統(tǒng)上運行,反之亦然,從而使Java成為獨立于平臺的語言。
圖1:Java虛擬機概述
1.1.1 JVM做什么?
Java虛擬機執(zhí)行以下操作:
- 加載所需的.class和jar文件
- 分配參考并驗證代碼
- 執(zhí)行代碼
- 為Java字節(jié)碼提供運行時環(huán)境
1.1.2 JVM內(nèi)部架構(gòu)
下圖顯示了符合JVM規(guī)范的Java虛擬機的關(guān)鍵內(nèi)部組件。
圖2:Java虛擬機架構(gòu)
下面分別解釋圖2中所示的類加載器和運行時數(shù)據(jù)區(qū)域組件。
1.2 ClassLoader子系統(tǒng)
類加載器子系統(tǒng)是Java虛擬機的基本核心,用于加載/讀取.class文件并將字節(jié)碼保存在JVM方法區(qū)域中。 該子系統(tǒng)處理動態(tài)類加載功能,并執(zhí)行三個主要功能,即:
- 加載 :此組件處理將.class文件從硬件系統(tǒng)加載到JVM內(nèi)存并存儲二進制數(shù)據(jù)(例如完全限定的類名,直接父類名,有關(guān)方法,變量,構(gòu)造函數(shù)的信息等)。在方法領(lǐng)域。 對于每個已加載的.class文件,JVM會立即在堆存儲器上創(chuàng)建一個類型為java.lang.class的對象。 請記住 ,即使開發(fā)人員多次調(diào)用一個類,也只會創(chuàng)建一個類對象。 類加載器主要有三種類型:
- Bootstrap或Primordial ClassLoader : 該類加載器負責加載rt.jar存在的內(nèi)部核心Java類以及java.lang.*包中存在的其他類。
- 鏈接 :此組件執(zhí)行類或接口的鏈接。 由于此組件涉及新數(shù)據(jù)結(jié)構(gòu)的分配,因此它可能會拋出OutOfMemoryError并執(zhí)行三個重要的活動:
- 驗證 :這是檢查類的二進制表示形式并驗證生成的.class文件是否有效的過程。
- 初始化 :此組件執(zhí)行類加載的最后階段,在該階段中,所有靜態(tài)變量都被分配了原始值,并且靜態(tài)塊從父類執(zhí)行到子類。 由于JVM是多線程的,因此此過程需要仔細的同步,并且某些線程可能會嘗試同時初始化同一類或接口。
圖3:ClassLoader子系統(tǒng)概述
1.2.1 ClassLoader如何在Java中工作?
Java中的類加載器以三個原則工作,即委托 , 可見性和唯一性 。
圖4:Java中的類加載機制
- 代表團 :據(jù)此:
- 每當虛擬機遇到類時,JVM都會檢查是否加載了指定的.class文件。
- 可見性 :據(jù)此:
- 應(yīng)用程序類加載器可以看到父類加載器加載的類,但反之亦然,例如,如果類是由系統(tǒng)類加載器加載的,而稍后再次嘗試使用擴展類加載器顯式加載相同的類,則將拋出ClassNotFoundException 。運行。
- 唯一性 :據(jù)此:
- 由父類加載器加載的類不應(yīng)該由子類加載器需要重新加載
1.2.2如何在Java中加載類?
類加載器是分層的。 應(yīng)用程序中的第一個類是借助static main()方法專門加載的。 所有后續(xù)類都可以通過靜態(tài)或動態(tài)類加載技術(shù)來加載。
- 靜態(tài)類加載 :在這種技術(shù)中,類是通過new運算符靜態(tài)加載的
- 動態(tài)類加載 :在這種技術(shù)中,使用Class.forName()或loadClass()方法以編程方式加載類。 兩者之間的區(qū)別在于,前者在加載對象后初始化該對象,而后者僅加載該類但不初始化該對象
1.3運行時數(shù)據(jù)區(qū)
如圖5所示,該子系統(tǒng)分為五個主要部分,即
圖5:JVM運行時數(shù)據(jù)區(qū)
- 方法區(qū)域 :此組件保存每個.class文件的類級別數(shù)據(jù),例如元數(shù)據(jù),常量運行時池,靜態(tài)變量,方法的代碼等。每個JVM只有一個方法區(qū)域,并且在所有類之間共享。 默認情況下,分配給該區(qū)域的內(nèi)存是由JVM分配的,或者可以根據(jù)計算需要增加。 以下異常情況與此區(qū)域相關(guān),即
- 如果方法區(qū)域不滿足內(nèi)存分配請求,那么JVM會拋出OutOfMemory錯誤
- 堆區(qū)域 :此組件是JVM內(nèi)存的一部分,所有對象及其對應(yīng)的實例變量和數(shù)組都存儲在JVM內(nèi)存中。 該內(nèi)存區(qū)域是在JVM啟動時創(chuàng)建的,并且只有一個堆區(qū)域跨多個線程共享,因為存儲在該區(qū)域中的數(shù)據(jù)不是線程安全的。 如果存儲在堆內(nèi)存中的對象沒有引用,則垃圾回收器 (即自動存儲管理系統(tǒng))回收該對象的內(nèi)存; 此區(qū)域中的對象永遠不會顯式釋放。 以下異常情況與此區(qū)域相關(guān),即
- 如果計算需要的堆空間超過可用的堆空間,那么JVM會拋出OutOfMemory錯誤
- 堆棧區(qū)域 :該組件還是JVM內(nèi)存的一部分,所有臨時變量都存儲在該內(nèi)存中。 該區(qū)域具有堆棧幀,并為每個線程分配一個幀。 一旦線程執(zhí)行完成,該框架也會被破壞。 堆棧區(qū)域是線程安全的,因為它不是共享資源,并且分為三個子實體,例如:
- 局部變量數(shù)組:虛擬機使用這些局部變量在方法調(diào)用時傳遞參數(shù)
以下異常情況與此區(qū)域相關(guān),即
- 如果線程處理要求虛擬機堆棧超出其允許的限制,則JVM會引發(fā)StackOverflow錯誤
- PC(程序計數(shù)器)寄存器 :該組件保存當前正在執(zhí)行的JVM指令的地址。 Java中的每個線程都有其自己的PC寄存器來保存當前執(zhí)行指令的地址
- 本機方法堆棧 :此組件用另一種語言編寫,并保存本機方法信息。 Java中的每個線程都有一個單獨的本機方法堆棧。 以下異常情況與此區(qū)域相關(guān),即
- 如果線程處理需要本機堆棧超出其允許的限制,則JVM會引發(fā)StackOverflow錯誤
這就是這篇文章的全部內(nèi)容。 學(xué)習愉快!
2.結(jié)論
在本教程中,開發(fā)人員對虛擬機ClassLoader和Runtime Data Areas組件進行了概述。 您可以在“ 下載”部分中下載示例代碼。
3.下載源代碼
這是虛擬機ClassLoader和Runtime Data Areas組件的教程。
下載您可以在此處下載本教程的源代碼: JVM_Example
翻譯自: https://www.javacodegeeks.com/2018/04/jvm-architecture-jvm-class-loader-and-runtime-data-areas.html
總結(jié)
以上是生活随笔為你收集整理的JVM体系结构:JVM类加载器和运行时数据区的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 批处理 设置电脑最佳性能_批处理最佳做法
- 下一篇: apache karaf_Apache