翻譯原文:https://dzone.com/articles/jvm-architecture-explainedjava
JVM架構解析算法
每個Java開發者都知道字節碼是被JRE執行。可是實際上許多人並不知道JRE是JVM的實現能解析字節碼,編譯代碼,而且執行。做爲一個開發者瞭解JVM的架構是很是重要的,由於它會使書寫代碼更加高效。在這篇文章中咱們將更加深刻地學習JVM架構和JVM不一樣的組成部分。bootstrap
什麼是JVM?數組
虛擬機是物理機器的軟件實現。Java是發展於WORA (Write Once Run Anywhere)這一觀點。編譯器將Java文件編譯成Java.class文件,而後這個java.class文件被放到JVM 中,裝載並執行java.class文件。下面是一個JVM架構圖表。安全
JVM如何工做架構
如圖表所示,JVM分爲三大部分jvm
1. 類加載子系統性能
2. 運行時數據區學習
3. 執行引擎優化
1. 類加載子系統
Java動態類加載功能是由類加載子系統提供的。它加載,連接,初始化在運行時第一次出現的類的class文件。
1.1 Loading
類在這一模塊被加載。Boot Strap class Loader, Extension class Loader, Application class Loader 這三個loader協助實現。
1. Boot Strap class Loader,負責加載位於bootstrap classpath下的類。
2. Extension ClassLoader,負責加載位於ext folder (jre\lib).下的類
3. Application ClassLoader,負責加載位於應用級別的路徑,路徑提到的環境變量等。
在加載時會有委派分層算法。
1.2 Linking
a) 驗證
字節碼驗證者將會驗證生成的字節碼是否符合規範,若是驗證失敗將獲得驗證錯誤。
b) 準備
對於全部的靜態變量,內存會分配,並設置默認值。
c) Resolve
全部的符號內存引用都被方法區的原始引用所取代。
1.3 初始化
這是類加載的最後階段,全部的靜態變量將被分配原始值,靜態塊將被執行。
2. 運行時數據區
運行時數據區主要被分爲5個模塊。
2.1. 方法區
全部的類級數據將被存儲在這裏,包括靜態變量。每一個JVM方法區只有一個,它是一個共享資源。
2.2. 堆區
全部的對象和他們相應的實例變量,數組都會被存儲到這裏,每一個JVM堆區只有一個。因爲方法區和堆區共享多個線程的內存,存儲數據不是線程安全的。
2.3. 棧區
每個線程,都會建立一個獨立的運行時棧,對於每一個方法調用,會在棧存儲器中建立一個棧幀條目。全部的本地變量都會在棧內存彙總建立,說棧區域是線程安全的,由於它不是一個共享資源。棧幀被分爲三個實體:
a) 局部變量數組-相關方法的局部變量及其值將會存儲在這裏
b) 操做數棧-若是須要任何中間操做,操做數棧將做爲運行時工做區來執行操做。
c) 幀數據-對應於該方法的全部符號存儲在這裏。在任何異常狀況下,捕獲的信息將保持在幀數據中。
2.4. PC 寄存器
每一個線程都有一個獨立的PC 寄存器, 以保持當前執行指令的地址,一旦這條指令被執行,PC 寄存器就更新至下一條指令
2.5. 本地方法棧
本地方法棧保存了本地方法信息,對於每個線程,將建立一個單獨的本地方法棧。
3. 執行引擎
通過運行時數據區分配的字節碼被執行引擎執行。執行引擎閱讀字節碼,並一塊一塊地執行。
3.1. 解釋器
解釋器解析字節碼很快,但執行很慢。解釋器的缺點是當一個方法被屢次調用,每一次都須要新的解釋。
3.2. JIT編譯器
JIT編譯器抵消了解釋器的缺點。執行引擎將藉助解釋器的幫助轉換字節碼,當它發現是重複的代碼時則使用JIT編譯器,編譯整個字節碼並更改成本地代碼。此本地代碼將直接用於重複的方法調用,從而提升了系統的性能。
a)中間代碼生成器-產生中間代碼。
b)代碼優化器-負責優化上面生成的中間代碼。
c)目標代碼生成器-負責生成機器代碼或者本地代碼。
d)實踐探查器-一個特殊的組件,負責發現熱點,如某個方法被屢次調用或者未被調用。
3.3. 垃圾回收
收集和移除未引用的對象。垃圾回收能夠經過調用「System.gc()」,但執行是沒有保證的。JVM的垃圾回收收集已經建立的對象。
Java Native Interface (JNI):JNI將和本地方法庫相互做用,併爲執行引擎提供所須要的本地庫。
Native Method Libraries(本地方法庫):它是一個被執行引擎所需的本地庫的集合。