類從JVM對其加載到卸載,它的整個生命週期包括如下幾個階段:html
其中,鏈接(Linking),又分爲驗證(Validation)、準備(Preparation)、解析(Resolution)3個子階段。java
在加載階段,JVM主要完成三件事:算法
1. 經過類的全限定名來查找、獲取定義此類的二進制字節流。數據庫
2. 將這個字節流所表明的靜態存儲結構轉化爲方法區中的運行時數據結構。網絡
3. 在Java堆中建立一個表明這個類的java.lang.Class對象,做爲方法區中靜態數據的訪問入口。數據結構
有如下幾種類加載器:函數
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; 若是父類加載器找不到類文件,則逐層由子類加載器處理。
類的鏈接(Linking),又分爲驗證(Validation)、準備(Preparation)、解析(Resolution)三個子階段。
2.1 驗證(Validation),驗證的做用是保證Class文件的字節流包含的信息符合JVM規範,不會給JVM形成危害。若是驗證失敗,就會拋出一個java.lang.VerifyError異常或其子類異常。類的驗證內容有:
2.2 準備(Preparation) 準備階段要作的事情就是爲靜態變量分配內存並設置默認值。在這個階段分配的僅爲類的static變量,而不包括類的實例變量。
2.3 解析(Resolution) 解析階段要作的事情就是將方法區常量池內的符號引用替換成直接引用。有如下四種類型的解析:類或接口的解析、屬性解析、方法解析、接口方法解析。
類的初始化就是把類的變量(包括實例變量)初始化爲正確的值、並執行 static{}塊、構造函數等。
何時會執行類的初始化呢?
類的卸載,即指垃圾回收器機制(GC)識別無用對象,並對無用對象佔用的內存空間進行回收。垃圾回收機制有如下幾種算法(但不限於這幾種):
關於垃圾回收機制的更多內容,請參考: http://www.importnew.com/16173.html