JVM第一篇 — JVM中類的生命週期

    類從JVM對其加載到卸載,它的整個生命週期包括如下幾個階段:html

  • 加載(Loading)
  • 鏈接(Linking)
  • 初始化(Initialization)
  • 使用(Using)
  • 卸載(Unloading)

    其中,鏈接(Linking),又分爲驗證(Validation)、準備(Preparation)、解析(Resolution)3個子階段。java

1 類的加載(Loading)

    在加載階段,JVM主要完成三件事:算法

    1. 經過類的全限定名來查找、獲取定義此類的二進制字節流。數據庫

    2. 將這個字節流所表明的靜態存儲結構轉化爲方法區中的運行時數據結構。網絡

    3. 在Java堆中建立一個表明這個類的java.lang.Class對象,做爲方法區中靜態數據的訪問入口。數據結構

1.1 加載途徑

  • 從本地系統直接加載
  • 經過網絡下載.class文件
  • 從zip、jar文件中加載.class文件
  • 從專有數據庫中提取.class文件
  • 將Java源文件動態編譯爲.class文件

1.2 加載邏輯

    有如下幾種類加載器:函數

  • BootstrapClassLoader(啓動類加載器):它加載System.getProperty("sun.boot.class.path")所指定jar,即目錄${JAVA_HOME中}/jre/lib、${JRE_HOME中}/jre/lib下的全部jar; Bootstrap ClassLoader由C++實現,它不是ClassLoader的子類,它是頂級的類加載器。spa

  • ExtClassLoader(擴展類加載器):它加載System.getProperty("java.ext.dirs")所指定jar,即目錄${JAVA_HOME中}/jre/lib/ext、${JRE_HOME中}/jre/lib/ext下的全部jar; 它是BootstrapClassLoader的子類。code

  • AppClassLoader(應用類加載器):它加載應用程序運行時指定的classpath下的jar; 它是ExtClassLoader的子類。htm

public static void main(String[] args) {
        //System.out.println(System.getProperty("sun.boot.class.path"));
        //System.out.println(System.getProperty("java.ext.dirs"));

        Book book= new Book();
        Class c = book.getClass();
        ClassLoader loader = c.getClassLoader();
        System.out.println(loader);
        System.out.println(loader.getParent());
        System.out.println(loader.getParent().getParent());
    }

    以上程序的執行結果爲:

sun.misc.Launcher$AppClassLoader@439a8942
    sun.misc.Launcher$ExtClassLoader@56a96eba
    null

    從上面的結果能夠看出,並無獲取到ExtClassLoader的父Loader,緣由是Bootstrap Loader是用C++語言實現的,找不到一個肯定的返回父Loader的方式,因而就返回null。

    運行一個程序時,老是由AppClassLoader開始加載指定的類,而後它會將加載任務轉交給父加載器,父類加載器再將向上轉交給BootstrapClassLoader; 若是父類加載器找不到類文件,則逐層由子類加載器處理。

2 類的鏈接(Linking)

    類的鏈接(Linking),又分爲驗證(Validation)、準備(Preparation)、解析(Resolution)三個子階段。

2.1 驗證(Validation),驗證的做用是保證Class文件的字節流包含的信息符合JVM規範,不會給JVM形成危害。若是驗證失敗,就會拋出一個java.lang.VerifyError異常或其子類異常。類的驗證內容有:

  • 文件格式驗證:驗證字節流文件是否符合Class文件格式的規範,而且能被當前虛擬機正確的處理。
  • 元數據驗證:是對字節碼描述的信息進行語義分析,以保證其描述的信息符合Java語言的規範。
  • 字節碼驗證:主要是進行數據流和控制流的分析,保證被校驗類的方法在運行時不會危害虛擬機。

2.2 準備(Preparation)     準備階段要作的事情就是爲靜態變量分配內存並設置默認值。在這個階段分配的僅爲類的static變量,而不包括類的實例變量。

2.3 解析(Resolution)     解析階段要作的事情就是將方法區常量池內的符號引用替換成直接引用。有如下四種類型的解析:類或接口的解析、屬性解析、方法解析、接口方法解析。

3 類的初始化(Initialization)

    類的初始化就是把類的變量(包括實例變量)初始化爲正確的值、並執行 static{}塊、構造函數等。

3.1 初始化時機

    何時會執行類的初始化呢?

  • 調用new建立類的實例;
  • 初始化類的子類;
  • 訪問類或接口的靜態變量;
  • 調用類的靜態方法;
  • 調用Class.forName()反射建立實例;(ClassLoader.loadClass()也可加載類,但不會執行初始化塊)

3.2 初始化步驟

  1. 若是這個類尚未被加載和鏈接,那先進行加載和鏈接;
  2. 若是這個類存在直接父類,那就先初始化直接的父類;(注意:在一個類加載器中,每一個類只能初始化一次);
  3. 若是類中存在初始化語句(如static變量、static塊),那就依次執行這些初始化語句。
  4. 執行構造函數。

4 類的使用(Using)

    

5 類的卸載(Unloading)

    類的卸載,即指垃圾回收器機制(GC)識別無用對象,並對無用對象佔用的內存空間進行回收。垃圾回收機制有如下幾種算法(但不限於這幾種):

  • 引用計數法(Reference Counting Collector)
  • tracing算法(Tracing Collector)
  • generation算法(Generational Collector)

    關於垃圾回收機制的更多內容,請參考: http://www.importnew.com/16173.html

相關文章
相關標籤/搜索