(原發於知乎, 按期同步至segmentfault, 原文地址:知乎-JVM入門系列-JVM總覽)
Java宣稱Write Once Run Everywhere,這意味着在一個平臺上開發的java程序能夠不加修改的運行在其餘平臺上面。能達成這個功能依賴的就是jvm屏蔽了底層的差別。java
當咱們編寫.java文件以後,編譯器會將其編譯成同名的.class文件。class文件是一個字節碼文件,jvm會加載而且執行它,下方就是總體框圖。segmentfault
(圖片來源:wikipedia-Java virtual machine)jvm
如圖所示,虛擬機主要能夠被分爲三塊:優化
類加載系統spa
運行時數據區線程
執行引擎code
類加載系統Class Loader Subsystem對象
類加載系統負責驗證而且加載.class文件,主要能夠劃分爲三個步驟:blog
加載(Loading)接口
連接(Linking)
初始化(Initialization)
加載
類文件在這一塊被加載到內存中去。類加載器(class loader)能夠劃分爲Boot Strap class Loader, Extension class Loader, and Application class Loader
Boot Strap class Loader - 加載系統引導類( $JAVA_HOME/jre/lib))
Extension class Loader - 加載拓展類($JAVA_HOME/jre/lib/ext)
Application class Loader - 也被稱爲User class loader, 負責加載應用層級的類
連接
Verify - 驗證字節碼是否正確
Prepare - 在這一步分配靜態變量而且設置默認值
Resolve - 全部的符號引用都會被替換成指向方法區的原始引用
初始化
這是類加載的最後一步,全部的靜態變量都會被賦值。執行順序是從上到下的,由父類到子類。
運行時數據區 Runtime Data Area
運行時數據區能夠劃分爲5個區域
方法區 - 保存類數據信息,包括成員信息,父類和接口信息,運行時常量池等,jvm共享
堆區 - 保存全部的對象信息,jvm共享
棧區 - 每一個線程獨有本身的棧,生命週期和線程一致
PC寄存器區 - 儲存當前執行指令的地址,若是執行的是是本地方法pc爲null
本地方法棧區 - 和棧區一致,只不過存放的是本地方法信息
執行引擎 Execution Engine
執行引擎負責執行代碼,執行引擎會依次讀取字節碼而且按順序執行。通常來講能夠劃分爲以下幾個組件
字節碼解釋器
字節碼解釋器(Bytecode Interpreter),就像名字顯示的同樣,是用來執行字節碼。優勢是執行開銷小,缺點是執行效率較低。
模板解釋器
和字節碼解釋器差很少,不同的地方在於直接把對應的指令集轉成本地代碼
JIT編譯器
能夠針對熱點代碼優化,執行開銷較大,可是可以針對性的優化,效率最高
垃圾收集器
負責回收再也不使用的對象,釋放和整理內存
Java Native Interface
Java native interface, 簡稱JNI。暴露了本地方法的接口,使得java能夠調用本地方法
Native Method Libraries
本地方法庫
參考: