JVM架構
從上圖可以很清晰的看出,jvm架構分成三大部分
- 類加載子系統
- 運行時數據區
- 執行引擎
1,類加載子系統
JAVA的動態類加載功能就是由類加載子系統完成的。類加載子系統在運行時第一次遇到一個class文件時就去加載、鏈接、初始化class文件。注意是運行時,不是編譯時。
1.1 加載
類首先由類加載子系統加載進來。具體分為啟動類加載器(BootStrap ClassLoader)、擴展類加載器(Extension ClassLoader)和應用類加載器(Application ClassLoader)三個類加載器。
- 啟動類加載器:優先級最高的類加載器。加載的是rt.jar
- 擴展類加載器:負責加載java.ext.dirs系統屬性指定的目錄下的jar,也會加載jdk安裝目錄下的jre/lib/ext文件夾下jar,如果我們自己大的jar包,放到這些目錄下,也會被擴展類加載器加載。
- 應用類加載器:負責加載應用程序classpath目錄下的所有jar和class文件。
加載過程遵循雙親委派機制
1.2 鏈接
- 校驗:進行二進制代碼的合法性驗證工作,如果非法會報錯。
- 準備:在這個階段所有的靜態變量會分配內存,并初始化類型的默認值。
- 解析:所有的符號引用替換成真正的內存地址引用
1.3初始化
類加載的隨后階段。此時進行所有靜態變量的初始化,靜態代碼塊也會得到執行。
2,運行時數據區
運行時數據區主要分五個部分。
- 方法區所有類級別的信息都存在這,包括類的靜態變量。一個JVM只有一個方法區,方法區是線程共享的。
- 堆區所有的對象實例及其實例變量都存在這。同樣一個JVM只有一個堆,堆是線程共享的。
- 棧區每個線程有自己獨立的棧。棧是線程安全的。每次方法調用產生一個棧幀。所有的本地變量在對應的棧內存中分配。一個棧幀又可以分成三部分局部變量表(Local Variable Array,簡稱LVA),顧名思義存儲本地變量操作數棧(Operand stack),進行運算幀數據(Frame data),存放的幀數據用于支持正常方法返回以及異常派發
- PC寄存器線程獨享,存儲當前執行的指令的地址。
- 本地方法棧線程獨享,存儲本地方法執行的信息。
3,執行引擎
二進制代碼是由執行引擎執行的。執行引擎可以分成三部分。
- 解釋器解釋器解析代碼快,但是執行慢。如果一個方法調用多次,對解釋器來說,要進行多次解釋執行。
- JIT即時編譯器JIT即時編譯器可以彌補解釋器的缺點。執行引擎使用解釋器編譯代碼,當它發現重復代碼時,使用JIT即時編譯器將重復代碼轉成本地方法代碼。這個本地方法代碼會在方法重復調用時直接執行,提高了效率。
- 垃圾回收器
4,本地方法接口
本地方法接口和本地方法庫交互,使執行引擎可以調用本地方法庫
5,本地方法庫
就是本地方法庫