[譯]一文了解JVM

原文地址:《The JVM Architecture Explained 》java

每一個Java開發者都知道字節碼是被JRE(Java運行時環境)所執行的。可是許多人並不知道實際上JRE是Java虛擬機(JVM)的實現。它分析字節碼,解釋代碼並執行它。做爲一個開發者,瞭解JVM的體系結構是很是重要的,由於它使咱們能更有效的編寫代碼。在這篇文章中,咱們將更深刻的瞭解Java中的JVM體系結構和JVM的不一樣組件。數組

什麼是JVM?

虛擬機是物理機器的軟件實現。Java語言當時是基於編寫一次處處運行的理念被開發出來的,其中處處運行指的是運行在虛擬機上。編譯器將java文件編譯成.class文件,而後.class文件被輸入到JVM中,JVM會加載並運行這些.class文件。下圖展現了JVM的體系結構。安全

JVM體系結構 多線程

JVMArchitecture.png

JVM是如何工做的?

正如上圖展現的,JVM被分爲如下三個主要的子系統:jvm

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

1.類加載器

Java的動態類加載功能是由類加載子系統處理。它加載,連接,並初始化類(當在運行時第一次引用該類時)。性能

1.1加載

類都經過該組件進行加載。BootStrap ClassLoader、 Extension ClassLoader、Application ClassLoader這三個類加載器協同完成這個目標。優化

  • BootStrap ClassLoader:負責從引導類路徑加載類,除了rt.jar。將給予此加載程序最高優先級。
  • Extension ClassLoader:負責加載ext文件夾中的類。
  • Application ClassLoader:負責從應用程序類路徑加載類。

以上這些類加載器將遵循雙親委託機制裝載類文件。(即當一個類須要加載時,先從Bootstrap加載,沒有的話,再從Extension加載,仍是沒有的話,才從Application加載。)線程

1.2連接
  1. 驗證:字節碼驗證器將會驗證生成的字節碼正確與否。若是驗證失敗,咱們將獲得驗證錯誤信息。
  2. 準備:爲全部靜態變量開闢內存空間並賦默認值。
  3. 解析:將全部符號引用替換爲方法區中的原始引用。
1.3初始化

這是類加載的最後階段。全部靜態變量將會被賦予初始值而且靜態構造塊將會被執行。翻譯

2.運行時數據區

運行時數據區被分爲五個主要的區域。3d

  1. 方法區:全部類級別的數據將會被存於此處。包括靜態變量。一個虛擬機僅有一個方法區。它屬於共享資源。
  2. 堆區:全部對象及對象中的實例變量和數組都將存於此處。一個虛擬機也僅有一個堆區。由於方法區和堆區在多線程狀況下是共享內存的,因此存於其中的數據並不是線程安全的。
  3. 虛擬機棧:對於每個線程,都將建立一個單獨的運行時方法棧。對於每個方法調用,棧中都會生成一個棧幀。全部本地變量都將在棧中建立。棧區域是線程安全的,由於它並不是共享資源。棧幀又被分爲三個主要組成:
    1. 局部變量數組:與方法相關,涉及多少局部變量以及相應的值將存在這裏。
    2. 操做數棧:若是須要執行任何中間操做,操做數棧充當運行時工做區來執行操做。
    3. 幀數據:與該方法對應的全部符號都存儲在這裏。在任何異常的狀況下,catch塊信息將會保存在幀數據中。
  4. 程序計數器:每一個線程都擁有獨立的程序計數器。它保存當前執行指令的地址,一旦指令執行,程序計數器將更新爲下一條指令。
  5. 本地方法棧:本地方法棧保存了本地方法調用信息。對於每個線程,都會建立獨立的本地方法棧。

3.執行引擎

分配到運行時數據區的字節碼將會被執行引擎執行。執行引擎將會讀取字節碼並逐個執行。

  1. 解釋器:解釋器解釋字節碼快,但執行慢。而且在屢次調用同一個方法時,都須要從新解釋。

  2. JIT編譯器:JIT編譯器彌補瞭解釋器的缺點。執行引擎會藉助解釋器去轉換字節碼。可是當它發現有重複的代碼時,會使用JIT去編譯整份字節碼並將它改成本地代碼。本地代碼將會被直接使用在重複的方法調用,從而提升系統的性能。

    1. 中間代碼生成器:生成中間代碼
    2. 代碼優化器:負責優化中間代碼
    3. 目標代碼生成器:負責生成機器碼或本地代碼
    4. 分析器:特殊組件,負責發現熱點代碼,即方法是否被屢次調用。
  3. 垃圾回收器:回收和刪除未被引用的對象。垃圾回收可被System.gc()方法觸發,可是不保證立馬執行。

筆者我的翻譯,若有錯誤請網友評論區指正。

轉自個人我的博客 vc2x.com

相關文章
相關標籤/搜索