天天看點

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檔案

類的使用與解除安裝

  • 使用 :正常的使用,調用類的方法等
  • 解除安裝 :從記憶體中解除安裝。