JVM之類加載機制
文章目錄
1)概述
2)類加載的過程
3)類加載器和雙親委派模型
概述
- 虛擬機從class文件加載到內存,並對數據進行校驗、轉換解析和初始化,最終形成可被虛擬機直接使用的Java類型的過程
- 類加載的時機
- 類從被加載到虛擬機內存中開始,到卸載出內存爲止,它的整個生命週期包括:
類加載的過程
- 加載
- 通過類的全限定名來獲取定義類的二進制字節流。
- 將該二進制字節流所代表的靜態存儲結構轉化爲方法區的運行時數據結構
- 在內存中生成一個代表這個類的
java.lang.Class
對象
- 驗證
- 爲了確保Class文件的字節流中包含的信息符合當前虛擬機的要求,並且不會危害虛擬機自身的安全。
- 可用
-Xverify:none
來關閉大部分的類驗證措施,以縮短虛擬機類加載的時間 - 1.文件格式驗證
- 保證輸入的字節流能正確的解析並存儲於方法區中,且格式上符合描述一個Java類型信息的要求
- 2.元數據驗證
- 對字節碼描述的信息進行語義分析,以保證其描述的信息符合Java語言規範的要求
- 3.字節碼驗證
- 對類的方法體進行校驗分析,保證被校驗類的方法在運行時不會做出危害虛擬機安全的事件
- 4.符號引用驗證
- 對類自身以外的信息進行匹配性校驗
- 準備
- 爲類變量分配內存,設置類變量初始值
- 解析
- 驗證,準備和解析稱爲連接
- 解析可能會在初始化之後再開始,它是將常量池的符號引用替換爲直接引用的過程
- 初始化
- 開始執行類中定義的Java代碼,執行類構造器()
- 遇到以下情況必須對類進行初始化
- 遇到
new、getstatic、putstatic或invokestatic
- 使用
java.lang.reflect
包的方法對類進行反射調用 - 當初始化一個類的時候,若發現其父類還未進行初始化,需先觸發其父類的初始化;
- 在虛擬機啓動時,需指定一個要執行的主類,虛擬機會先初始化它;
- 當使用JDK1.7的動態語言支持時,若一個java.lang.invoke.MethodHandle實例最後的解析結果爲REF_getStatic、REF_putStatic、REF_invokeStatic的方法句柄,且這個方法句柄所對應的類未進行初始化,需先觸發其初始化。
- 遇到
類加載器
- 類加載器
- 每個類加載器都擁有一個獨立的類名稱空間,它不僅用於加載類,還和這個類本身一起作爲在JVM中的唯一標識。比較兩個類是否相等,只要看它們是否由同一個類加載器加載。
- 啓動類加載器
- 虛擬機自身的一部分
- 其他類加載器
- 獨立於虛擬機外部
- 擴展類加載器
- 應用程序類加載器
- 自定義類加載器
- 雙親委派模型
- 表示類加載器之間的層次關係
- 除了頂層啓動類加載器外,其餘類加載器都應有自己的父類加載器,通過組合關係來複用加載器的代碼
- 若一個類加載器收到了類加載的請求,它先會把這個請求委派給父類加載器,並向上傳遞,最終請求都傳送到頂層的啓動類加載器中。只有當父加載器反饋自己無法完成這個加載請求時,子加載器纔會嘗試自己去加載。
參考
《深入理解Java虛擬機》
理解JVM之類加載機制