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