【JVM】類加載

    瘋狂講義看了一遍,jvm看了一遍,也算清晰了些。


一、what


    虛擬機把描述類的數據從Class文件加載到內存,並對數據進行校驗、轉換解析和初始化,最終形成可以被虛擬機直接使用的Java類型,這就是虛擬機的類加載機制。


二、when


     Java語言裏,類型的加載、連接和初始化過程都是在程序運行期間完成的。


三、how


    類從被加載到虛擬機內存中開始,到卸載出內存爲止,它的聲明週期包括:加載、驗證、準備、解析、初始化、使用和卸載。發生順序如下所示:

        

    加載、驗證、準備、初始化和卸載的順序是確定的,類的加載過程按照這種順序按部就班的開始,解析階段不一定,它可以在初始化階段之後再開始,通常會在一個階段執行的過程中調用、激活另外一個階段。


(一)加載


這是類加載機制的第一步,主要完成三件事:


    1、通過一個類的全限定名(包名與類名)來獲取定義此類的二進制字節流(Class文件)。(獲取的方式可以從zip包中讀取,最終成爲日後jar,ear,war格式的基礎;從網絡中獲取;運行時計算生成,比如動態代理;其他文件生成,比如jsp文件……)

    2、將這個字節流所代表的靜態存儲結構轉化爲方法區的運行時數據結構。這裏只是轉化了數據結構,並未合併數據。(方法區就是用來存放已被加載的類信息,常量,靜態變量,編譯後的代碼的運行時內存區域)

    3、在內存中生成一個代表這個類的java.lang.Class對象,作爲方法區這個類的各種數據的訪問入口。這個Class對象並沒有規定是在Java堆內存中,它比較特殊,雖爲對象,但存放在方法區中。


(二)連接


    類的加載過程後生成了類的java.lang.Class對象,接着會進入連接階段,連接階段負責將類的二進制數據合併入JRE(Java運行時環境)中。類的連接大致分三個階段:
    1.驗證:驗證被加載後的類是否有正確的結構,類數據是否會符合虛擬機的要求,確保不會危害虛擬機安全。
    2.準備:爲類的靜態變量(static filed)在方法區分配內存,並賦默認初值(0值或null值)。如static int a = 100;

     靜態變量a就會在準備階段被賦默認值0。

     對於一般的成員變量是在類實例化時候,隨對象一起分配在堆內存中。

     另外,靜態常量(static final filed)會在準備階段賦程序設定的初值,如static final int a = 123;  靜態常量a就會在準備階段被直接賦值爲123,對於靜態變量,這個操作是在初始化階段進行的。

3.解析:jvm將常量池內的符號引用替換爲直接引用的過程。


(三)初始化


    是類加載的最後一步,到這個階段,才真正開始執行類中定義的Java程序代碼。在準備階段,變量已經賦過一次系統要求的初始值,這個階段開始後,根據程序員通過程序制定的主觀計劃去初始化類變量和其他資源。

Java虛擬機規範中嚴格規定了有且只有五種情況必須對類進行初始化

     1、使用new字節碼指令創建類的實例,或者使用getstatic、putstatic讀取或設置一個靜態字段的值(放入常量池中的常量除外),或者調用一個靜態方法的時候,對應類必須進行過初始化。

     2、通過java.lang.reflect包的方法對類進行反射調用的時候,如果類沒有進行過初始化,則要首先進行初始化。

     3、當初始化一個類的時候,如果發現其父類沒有進行過初始化,則首先觸發父類初始化。

     4、當虛擬機啓動時,用戶需要指定一個主類(包含main()方法的類),虛擬機會首先初始化這個類。

     5、使用jdk1.7的動態語言支持時,如果一個java.lang.invoke.MethodHandle實例最後的解析結果REF_getStatic、REF_putStatic、RE_invokeStatic的方法句柄,並且這個方法句柄對應的類沒有進行初始化,則需要先觸發其初始化。


     注意:虛擬機規範使用了“有且只有”這個詞描述,這五種情況被稱爲“主動引用”,除了這五種情況,所有其他的類引用方式都不會觸發類初始化,被稱爲“被動引用”。


被動引用:


  (1)靜態常量在編譯階段就會被存入調用類的常量池中,不會引用到定義常量的類,這是一個特例,需要特別記憶,不會觸發類的初始化

  (2)通過子類引用父類的靜態字段,對於父類屬於“主動引用”的第一種情況,對於子類,沒有符合“主動引用”的情況,故子類不會進行初始化。

  (3)通過數組來引用類,不會觸發類的初始化,因爲是數組new,而類沒有被new,所以沒有觸發任何“主動引用”條款,屬於“被動引用”。


ps:本篇博客內容基本爲jvm高級特性與最佳實踐這本書,博文作爲知識梳理。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章