JVM加載class文件的原理機制


       Java 語言是一種具有動態性的解釋型語言,類(Class)只有被加載到 JVM 后才能運行。當運行指定程序時,JVM 會將編譯生成的 .class 文件按照需求和一定的規則加載到內存中,並組織成為一個完整的 Java 應用程序。這個加載過程是由類加載器完成,具體來說,就是由 ClassLoader 和它的子類來實現的。

       類加載器本身也是一個類,其實質是把類文件從硬盤讀取到內存中。類的加載方式分為隱式加載顯示加載隱式加載指的是程序在使用 new 等方式創建對象時,會隱式地調用類的加載器把對應的類加載到 JVM 中。顯示加載指的是通過直接調用 class.forName() 方法來把所需的類加載到 JVM中。

        任何一個工程項目都是由許多類組成的,當程序啟動時,只把需要的類加載到 JVM 中,其他類只有被使用到的時候才會被加載,采用這種方法一方面可以加快加載速度,另一方面可以節約程序運行時對內存的開銷。此外,在 Java 語言中,每個類或接口都對應一個 .class 文件,這些文件可以被看成是一個個可以被動態加載的單元,因此當只有部分類被修改時,只需要重新編譯變化的類即可,而不需要重新編譯所有文件,因此加快了編譯速度。

        在 Java 語言中,類的加載是動態的,它並不會一次性將所有類全部加載后再運行,而是保證程序運行的基礎類(例如基類)完全加載到 JVM中,至於其他類,則在需要的時候才加載。

類加載的主要步驟:

1. 加載

加載是類加載的第一個過程,在這個階段,將完成一下三件事情:

通過一個類的全限定名獲取該類的二進制流。
將該二進制流中的靜態存儲結構轉化為方法去運行時數據結構。
在內存中生成該類的 Class 對象,作為該類的數據訪問入口。

2. 驗證

驗證的目的是為了確保 Class 文件的字節流中的信息不回危害到虛擬機.在該階段主要完成以下四鍾驗證:

   文件格式驗證:驗證字節流是否符合 Class 文件的規范,如主次版本號是否在當前虛擬機范圍內,常量池中的常量是否有不被支持的類型.

   元數據驗證:對字節碼描述的信息進行語義分析,如這個類是否有父類,是否集成了不被繼承的類等。

   字節碼驗證是整個驗證過程中最復雜的一個階段,通過驗證數據流和控制流的分析,確定程序語義是否正確,主要針對方法體的驗證。如:方法中的

類型轉換是否正確,跳轉指令是否正確等。

 

   符號引用驗證:這個動作在后面的解析過程中發生,主要是為了確保解析動作能正確執行。


3. 准備,給類中的靜態變量分配存儲空間

       准備階段是為類的靜態變量分配內存並將其初始化為默認值,這些內存都將在方法區中進行分配。准備階段不分配類中的實例變量的內存,實例變量將會在對象實例化時隨着對象一起分配在 Java 堆中。


4. 解析,將符號引用轉換為直接引用(這一步可選)

該階段主要完成符號引用到直接引用的轉換動作。解析動作並不一定在初始化動作完成之前,也有可能在初始化之后。


5. 初始化。對靜態變量和靜態代碼塊執行初始化工作。

       初始化時類加載的最后一步,前面的類加載過程,除了在加載階段用戶應用程序可以通過自定義類加載器參與之外,其余動作完全由虛擬機主導和控制。到了初始化階段,才真正開始執行類中定義的Java 程序代碼。

6. 使用

7. 卸載


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM