Java虛擬機JVM架構解析

每個Java開發人員都知道字節碼將由JRE (Java運行時環境)運行。但是許多人不知道JRE是Java虛擬機(JVM)的實現,它分析字節碼、解釋並執行代碼。作為開發人員,清楚瞭解JVM的體系結構非常重要,因為它能讓我們更有效地編寫代碼。在本文中,我們將更深入地瞭解Java中的JVM架構以及JVM中的各種組件。

什麼是JVM?

虛擬機是物理機器的軟件實現。Java是用WORA(Write Once Run Anywhere)的概念開發的,它在虛擬機上運行。編譯器將Java文件編譯成Java .class文件,然後將那個.class文件輸入到JVM中,JVM會加載並執行類文件。

下面是JVM的架構圖。

JVM 架構圖

Java虛擬機JVM架構解析

JVM 是如何工作的?

正如上面的架構圖所示,JVM被劃分為三個主要的子系統:

  1. 類裝載子系統(Class Loader Subsystem)
  2. 運行時數據區(Runtime Data Area)
  3. 執行引擎(Execution Engine)

1. 類裝載子系統

Java的動態類裝載功能由類裝載子系統來實現。它可以裝載,鏈接,還有當它在運行時(而不是編譯時)第一次引用類時,進行初始化類文件。

1.1 裝載

這個組件功能是加載類。總共有三種類裝載器:Boot Strap class Loader, Extension class Loader, 和 Application class Loader。

  1. Boot Strap ClassLoader – 負責從 bootstrap classpath加載類,在基礎類庫rt.jar中,具有最高的優先級類裝載器。
  2. Extension ClassLoader – 負責加載ext文件夾(jre\lib)中的類。
  3. Application ClassLoader –負責加載應用程序級類Class Path、Path和環境變量等。

上面的類加載器在加載類文件時,將遵循 Delegation Hierarchy Algorithm 算法。

1.2 鏈接Linking

  1. 驗證Verify – 字節碼驗證器將驗證生成的字節碼是否正確,如果驗證失敗,我們將得到驗證錯誤。
  2. 準備Prepare – 對於所有靜態變量,內存將被分配並分配默認值。
  3. 解析Resolve – 所有符號內存引用都替換為來自方法區域的原始引用。

1.3 初始化Initialization

這是類裝載的最後一個階段,在這裡所有靜態變量都將被賦與原始值,靜態代碼塊將被執行。

2. Runtime Data Area

運行時數據區域分為5個主要部分:

  1. 方法區域(Method Area) –所有的類級別數據都將存儲在這裡,包括靜態變量。每個JVM只有一個共享的方法區域。
  2. 堆區域 (Heap Area) –所有對象及其對應的實例變量和數組都將存儲在這裡。每個JVM也只有一個堆區域。由於方法和堆區域為多個線程共享內存,所以堆區存儲的數據並不是線程安全的。
  3. 棧區域(Stack Area) – 對於每個線程,將創建一個單獨的運行時棧。對於每個方法調用,將在堆棧內存中創建一個條目,稱為堆棧幀(Stack Frame)。所有本地變量都將在棧內存中創建。棧區域是線程安全的,因為它不是共享資源。

堆棧框架分為三個子實體:

  • 局部變量數組(Local Variable Array)
    – 與方法相關的局部變量以及相應的值將存儲在這裡。
  • 操作數堆棧(Operand stack) –如果需要執行任何中間操作,操作數堆棧作為運行時工作區來執行操作。
  • Frame data – 與方法對應的所有符號都存儲在這裡。異常處理中,Catch塊信息將在框架數據中維護。

4、PC Registers – 每一個線程都有單獨的PC寄存器,在執行指令後,保存當前執行指令的地址,PC寄存器將隨下一個指令進行更新。

5、本地方法棧(Native Method stacks )–本地方法棧保存本地方法的信息。為每一個線程,將創建一個單獨的本地方法棧。

3. 執行引擎

分配給運行時數據區域的字節碼將由執行引擎執行。執行引擎讀取字節碼並逐個執行它。

  1. Interpreter – 解釋器解釋字節碼很快,但執行緩慢。解釋器的缺點是,當一個方法被多次調用時,每次都需要新的解釋。
  2. JIT Compiler – JIT編譯器消除了解釋器的缺點。執行引擎將使用解釋器的幫助來轉換字節代碼,但是當它發現重複的代碼時,它使用JIT編譯器,它編譯整個字節碼並將其更改為本機代碼。這種本機代碼將直接用於重複的方法調用,從而提高系統的性能。
  3. Intermediate Code generator – 生成中間代碼
  4. Code Optimizer – 負責優化上面生成的中間代碼
  5. Target Code Generator – 負責生成機器代碼或本機代碼
  6. Profiler – 一種特殊的組件,負責查找hotspots,即該方法是否被多次調用。
  7. 垃圾回收:收集和刪除未引用的對象。可以通過調用“System.gc()”來觸發垃圾收集,但不會立即執行(執行時機由GC決定)。JVM的垃圾回收收集已創建的對象。

Java Native Interface (JNI):

JNI將與本地的方法庫交互併為執行引擎提供所需的本地庫。

Native Method Libraries:它是執行引擎所需的本地庫的集合。


分享到:


相關文章: