關于文章
JVM系列每一篇文章我都錄制了對應的視頻,由于CSDN不能直接發送視頻資料,如果想要作者錄制的免費視頻資料,可以加QQ:3139882589,這個是作者QQ,如果有問題想跟作者咨詢,也可以加到我們的java技術交流QQ群,加作者請備注暗號 [CSDN]

類加載機制
類加載機制本質上就是虛擬機把Class檔案加載到記憶體,并對資料進行校驗,轉換決議和初始化,形成可以虛擬機直接使用的Java型別,即java.lang.Class,
同樣,我們去官網查看下,還是JDK8版本

我們可以看見Loading,Linking,以及Initializing,也就是我們常說的裝載,鏈接以及初始化,那么我們去學習就可以根據這個進行學習,其實我們一個類的生命周期還會加上使用以及卸載階段,所以就有了下面這張圖,

3.1 裝載(Load)
作用:查找和匯入class檔案
(1)通過一個類的全限定名獲取定義此類的二進制位元組流
(2)將這個位元組流所代表的靜態存盤結構轉化為方法區的運行時資料結構
(3)在Java堆中生成一個代表這個類的java.lang.Class物件,作為對方法區中這些資料的訪問入口
Class物件封裝了類在方法區內的資料結構,并且向Java程式員提供了訪問方法區內的資料結構的介面,在Java堆中生成一個代表這個類的java.lang.Class物件,作為對方法區中這些資料的訪問入口
方法區:類資訊,靜態變數,常量,即時編譯器編譯后的代碼
堆:代表類的java.lang.Class物件
3.2 鏈接(Link)
2.2.2.1 驗證(Verify)
保證被加載類的正確性
- 檔案格式驗證
- 元資料驗證
- 位元組碼驗證
- 符號參考驗證
2.2.2.2 準備(Prepare)
為類的靜態變數分配記憶體,并將其初始化為默認值

public class Demo1 {
private static int i;
public static void main(String[] args) {
// 正常列印出0,因為靜態變數i在準備階段會有默認值0
System.out.println(i);
}
}
public class Demo2 {
public static void main(String[] args) {
// 編譯通不過,因為區域變數沒有賦值不能被使用
int i;
System.out.println(i);
}
}
2.2.2.3 決議(Resolve)
把類中的符號參考轉換為直接參考
符號參考就是一組符號來描述目標,可以是任何字面量, 直接參考就是直接指向目標的指標、相對偏移量或一個間接定位到目標的句柄,
決議階段是虛擬機將常量池內的符號參考替換為直接參考的程序,
決議動作主要針對類或介面、欄位、類方法、介面方法、方法型別、方法句柄和呼叫限定符7類符號參考進
行,
2.2.3 初始化(Initialize)
對類的靜態變數,靜態代碼塊執行初始化操作

2.2.4 類加載器ClassLoader
在裝載(Load)階段,其中第(1)步:通過類的全限定名獲取其定義的二進制位元組流,需要借助類裝載器完成,顧名思義,就是用來裝載Class檔案的,
2.2.4.1 分類
1)Bootstrap ClassLoader 負責加載$JAVA_HOME中 jre/lib/rt.jar 里所有的class或Xbootclassoath選項指定的jar包,由C++實作,不是ClassLoader子類,
2)Extension ClassLoader 負責加載java平臺中擴展功能的一些jar包,包括$JAVA_HOME中jre/lib/*.jar 或 -Djava.ext.dirs指定目錄下的jar包,
3)App ClassLoader 負責加載classpath中指定的jar包及 Djava.class.path 所指定目錄下的類和jar包,
4)Custom ClassLoader 通過java.lang.ClassLoader的子類自定義加載class,屬于應用程式根據自身需要自定義的ClassLoader,如tomcat、jboss都會根據j2ee規范自行實作ClassLoader,
2.2.4.2 圖解
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-z7zc1RJN-1628927138278)(C:/Users/milo.DESKTOP-0NH7R90/Desktop/images/10.png)]
public class Demo3 {
public static void main(String[] args) {
// App ClassLoader
System.out.println(new Worker().getClass().getClassLoader());
// Ext ClassLoader
System.out.println(new Worker().getClass().getClassLoader().getParent());
// Bootstrap ClassLoader
System.out.println(new Worker().getClass().getClassLoader().getParent().getParent());
System.out.println(new String().getClass().getClassLoader());
}
}
sun.misc.Launcher$AppClassLoader@18b4aac2
sun.misc.Launcher$ExtClassLoader@3a71f4dd
null
null
2.2.4.3 加載原則[雙親委派]
(1)檢查某個類是否已經加載
自底向上,從Custom ClassLoader到BootStrap ClassLoader逐層檢查,只要某個Classloader已加載,就視為已加載此類,保證此類只所有ClassLoader加載一次,
(2)加載的順序
自頂向下,也就是由上層來逐層嘗試加載此類,

2.2.4.4 破壞雙親委派
(1)tomcat

(2)SPI機制
(3)OSGi
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/294076.html
標籤:其他
