【轉】JVM 架構解讀

每一個Java開發人員都知道字節碼由JRE(Java運行時環境)執行。但許多人不知道JRE是Java Virtual Machine(JVM)的實現,它分析字節碼,解釋代碼並執行它。做爲開發人員,咱們應該知道JVM的架構是很是重要的,由於它使咱們可以更有效地編寫代碼。在本文中,咱們將更深刻地瞭解Java中的JVM架構和JVM的不一樣組件。css

什麼是JVM?

Virtual Machine是物理機器的軟件實現。Java是用在VM上運行的WORA(Write Once Run Anywhere)概念而開發的。編譯器將Java文件編譯爲Java .class文件,而後將.class文件輸入到JVM中,JVM會加載並執行類文件。下面是JVM的架構圖。html

JVM如何工做?

如上面的架構圖所示,JVM分爲三個主要子系統:web

  1. 類加載器子系統
  2. 運行時數據區
  3. 執行引擎

1.類加載器子系統

Java的動態類加載功能由類加載器子系統處理。它在運行時,而不是編譯時首次引用類的時候加載、連接、並初始化類文件。算法

1.1加載bootstrap

類將經過此組件加載。Boot Strap Class Loader,Extension Class Loader和Application Class Loader是有助於實現的三個類加載器。數組

  1. Boot Strap Class Loader——負責加載來自於Bootstrap類路徑的類,就是rt.jar。此加載程序將給予最高優先級。
  2. Extension Class Loader——負責加載在ext文件夾(jre \ lib)內的類。
  3. Application Class Loader——負責加載應用程序級類路徑,路徑提到環境變量等

上面的類記載器在加載類文件時遵循Delegation Hierarchy 算法。安全

1.2連接架構

  1. 驗證——字節碼驗證器將驗證生成的字節碼是否正確,若是驗證失敗,咱們將獲得verification error。
  2. 準備——對於全部的靜態變量,內存將被分配和配置默認值。
  3. 解決——全部的符號存儲器引用都將替換爲來自Method Area的原始引用。

1.3初始化性能

這是類加載的最後階段,這裏全部的靜態變量都將被賦予原始值,並執行靜態塊。優化

2.運行時數據區

運行時數據區分爲5個主要組件:

方法區——全部的類級別數據將存儲在這裏,包括靜態變量。每一個JVM只有一個方法區,而且它是一個共享資源。

堆區域——全部對象及其對應的實例變量和數組將存儲在這裏。每一個JVM也有一個堆區域。因爲方法和堆區域共享多個線程的內存,所以所存儲的數據非線程安全。

堆棧區——對於每一個線程,將建立一個單獨的運行時棧。對於每一個方法調用,將在堆棧存儲器中產生一個條目,稱爲堆棧幀。全部局部變量將在堆棧內存中建立。堆棧區域是線程安全的,由於它不是共享資源。堆棧幀分爲三個子元素:

  1. 局部變量數組——與方法相關,涉及局部變量以及將在此存儲的相應值的多少。
  2. 操做數堆棧——若是須要執行任何中間操做,那麼操做數堆棧將充當運行時工做空間來執行操做。
  3. 幀數據——對應於方法的全部符號存儲在此處。在任何異常的狀況下,捕捉塊信息將被保持在幀數據中。

PC寄存器——每一個線程都有單獨的PC寄存器,用於保存當前執行指令的地址,一旦指令執行,PC寄存器將更新到下一條指令。

本地方法堆棧——本地方法堆棧保存本地方法信息。對於每一個線程,將建立一個單獨的本地方法堆棧。

3.執行引擎

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

解釋器——解釋器解釋字節碼較快,但執行慢。解釋器的缺點是當一個方法被屢次調用時,每次都須要新的解析。

JIT編譯器——JIT編譯器消除了解釋器的缺點。執行引擎將在轉換字節碼時使用解釋器的幫助,可是當它發現重複的代碼時,它使用JIT編譯器,編譯器會編譯整個字節碼並將其更改成本地代碼。這個本地代碼將直接用於重複的方法調用,從而提升系統性能。

  1. 中間代碼生成器——生成中間代碼
  2. 代碼優化器——負責優化上面生成的中間代碼
  3. 目標代碼生成器——負責生成機器代碼或本地代碼
  4. 分析器——一個特殊組件,負責查找熱點,即該方法是否被屢次調用。

垃圾收集器:收集和刪除未引用的對象。能夠經過調用「System.gc()」觸發垃圾收集器,但不能保證執行。JVM的垃圾回收收集建立的對象。

Java本機接口(JNI):JNI將與本地方法庫進行交互,並提供執行引擎所需的本地庫。

本地方法庫:它是執行引擎所需的本地庫的集合。

相關文章
相關標籤/搜索