加載
|
在加載階段,虛擬機主要完成三件事: 1.通過一個類的全限定名來獲取定義此類的二進制字節流。 2.將這個字節流所代表的靜態存儲結構轉化為方法區域的運行時數據結構。 3.在Java堆中生成一個代表這個類的java.lang.Class對象,作為方法區域數據的訪問入口 |
驗證
|
驗證階段作用是保證Class文件的字節流包含的信息符合JVM規范,不會給JVM造成危害。如果驗證失敗,就會拋出一個java.lang.VerifyError異常或其子類異常。驗證過程分為四個階段 1.文件格式驗證:驗證字節流文件是否符合Class文件格式的規范,並且能被當前虛擬機正確的處理。 2.元數據驗證:是對字節碼描述的信息進行語義分析,以保證其描述的信息符合Java語言的規范。 3.字節碼驗證:主要是進行數據流和控制流的分析,保證被校驗類的方法在運行時不會危害虛擬機。 4.符號引用驗證:符號引用驗證發生在虛擬機將符號引用轉化為直接引用的時候,這個轉化動作將在解析階段中發生。 |
准備
|
准備階段為變量分配內存並設置類變量的初始化。在這個階段分配的僅為類的變量(static修飾的變量),而不包括類的實例變量。對已非final的變量,JVM會將其設置成“零值”,而不是其賦值語句的值: pirvate static int size = 12; 那么在這個階段,size的值為0,而不是12。 final修飾的類變量將會賦值成真實的值。 |
解析 |
|
初始化
|
在准備階段,類變量已經經過一次初始化了,在這個階段,則是根據程序員通過程序制定的計划去初始化類的變量和其他資源。這些資源有static{}塊,構造函數,父類的初始化等。 至於使用和卸載階段階段,這里不再過多說明,使用過程就是根據程序定義的行為執行,卸載由GC完成。 |
使用
|
新線程---程序計數器----jvm棧執行(對象引用)-----堆內存(直接引用)----方法區
|
卸載
|
GC垃圾回收
|
1)啟動類加載器(Bootstrap ClassLoader):負責加載JAVA_HOME\lib目錄中並且能被虛擬機識別的類庫到JVM內存中,如果名稱不符合的類庫即使放在lib目錄中也不會被加載。該類加載器無法被Java程序直接引用。
2)擴展類加載器(Extension ClassLoader):按《深入理解java虛擬機》這本書上所說,該加載器主要是負責加載JAVA_HOME\lib\ext目錄中的類庫,但是貌似在JDK的安裝目錄下,沒看到該指定的目錄。該加載器可以被開發者直接使用。
3)應用程序類加載器(Application ClassLoader):該類加載器也稱為系統類加載器,它負責加載用戶類路徑(Classpath)上所指定的類庫,開發者可以直接使用該類加載器,如果應用程序中沒有自定義過自己的類加載器,一般情況下這個就是程序中默認的類加載器。
機制
|
從左到右加載:首先將加載任務委托給父類加載器,依次遞歸,如果父類加載器可以完成類加載任務,就成功返回;只有父類加載器無法完成此加載任務時,才自己去加載。 |
意義
|
防止內存中出現多份同樣的字節碼
使用委托機制,會遞歸的向父類查找,如果類A中引用了類B,Java虛擬機將使用加載類A的類加載器去加載類B,如果A加載器已加載類A,那么B使用A的類加載器進行加載時,就不會在加載類A的字節碼了
|
方法
|
《1》啟動(Bootstrap)類加載器 《2》標准擴展(Extension)類加載器 《3》應用程序類加載器(Application ) 《4》上下文(Custom)類加載器 |