jvm原理(1)類加載器深入解析與階段分解

類加載

  • 在Java代碼中,類型(class 、interface、 enum etc)的加載(將字節碼從磁盤加載到內存),連接(類與類之間的關係的連接)與初始化過程都是在程序運行期間完成的,加載,連接,初始化順序不是固定的,不同的虛擬機實現不一樣。
  • 提供了更大的靈活性,增加了更多的可能性。

類加載器深入剖析

  • Java虛擬機與程序的週期
  • 在如下幾種情況下,Java虛擬機將結束生命週期。
    • 執行了System.ext()方法。
    • 程序正常執行結束
    • 程序在執行過程中遇到了異常或錯誤而異常終止。
    • 由於操作系統錯誤而導致Java虛擬機進程終止。
    • -

類的加載、連接與初始化

  • 加載:查找並加載類的二進制數據
  • 連接:
    • 驗證:確保被加載類的正確性。
    • 準備:爲類的靜態變量分配內存,並將其初始化爲默認值
    • 解析:把類中的符號引用裝換爲直接引用
  • 初始化:爲類的靜態變量賦予正確的初始值


  • Java程序對類的使用方式可分爲2種:
    - 主動使用
    - 被動使用

  • 所有的Java虛擬機實現必須在每個類或者接口被Java程序“首次主動使用”時才初始化他們。

  • 主動使用(七種)

    • 創建類的實例。
    • 訪問某個類或者接口的靜態變量,或者對該靜態變量賦值。
    • 調用類的靜態方法。
    • 反射 (如Class.forName(“com.test.Test”))
    • 初始化一個類的子類
    • Jav啊虛擬機啓動時被標明爲啓動類的類(Java Test)
    • JDK1.7開始提供的動態 語言支持:
      Java.lang.invoke.MethodHandle實例的解析結果REF_getStattic REF_putStatic REF_invokeStatic句柄對應的類如果沒有初始化,則初始化(瞭解)
      除了以上七中情況,其他使用Java類的方式都被看做是對類的被動使用,都不會導致類的初始化(指的是加載,連接,初始化這個步驟的初始化)

實例介紹:


public class MyTest {
/*
對於靜態字段來說,只有直接定義該字段的類纔會被初始化
當一個類初始化時,要求其父類全部都已經初始化完畢了
-XX:+TraceClassLoading 用於追蹤類的加載信息並打印出來
-XX:+<option> 表示開啓option選項
-XX:-<option> 表示關閉option選項
-XX:<option>=<value>,表示將option的選項的值設置爲value
 */
    public static void main(String[] args) {
        //直接使用父類的變量 ,子類不會初始化,雖有用了子類的標識符
        System.out.println(MyChild.str);
        /*
        MyParent1 static block
        hello world
         */

        //直接調用子類的變量 會首先初始化父類,然後再初始化子類
       // System.out.println(MyChild.str2);
        /*
        MyParent1 static block
        MyChild static bloack
        welcome
         */
    }

}

class MyParent1{
    public static String str  = "hello world";
    static{
        System.out.println("MyParent1 static block");
    }
}

class MyChild extends  MyParent1{
    public static String str2 = "welcome";
    static{
        System.out.println("MyChild static bloack");
    }
}

類的加載:

  • 類的加載指的是將類的.class文件中的二進制數據讀入到內存中,將其放在運行時數據區的方法區,然後在內存中創建一個Java.lang.Class對象(規範並未說明Class對象位於哪裏,HotPot虛擬機將其放在了方法區中)用來封裝類在方法區內的數據結構。
  • 加載.class文件的方式
    • 從本地系統中直接加載
    • 通過網絡下載.class文件
    • 從zip,jar等歸檔文件中加載.class文件
    • 從專有數據庫中提取 .class文件
    • 將Java源文件動態編譯爲.class文件

類的使用與卸載

  • 使用 :正常的使用,調用類的方法等
  • 卸載 :從內存中卸載。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章