JVM的類加載過程詳細說明
一、基礎(chǔ)知識
我們平時寫的Java寫代碼一般都是.java文件,編譯成為.class字節(jié)碼文件,然后類加載器把.class文件加載到JVM內(nèi)存中,接下來JVM就執(zhí)行我們的字節(jié)碼文件,整個過程就是這樣。
畫個圖方便大家好理解:

類加載過程其實非常瑣碎且復雜,但是我們只要把握其中的核心工作原理即可
一個類從加載到使用會經(jīng)歷以下步驟:
加載-〉驗證-〉準備-〉解析-〉初始化-〉使用-〉卸載
以以下ClassLoadDemo類代碼舉例:
/**
* @author god-jiang
* @date 2021/5/29
*/
public class ClassLoadDemo {
private static int count = 666;
public static void main(String[] args) {
ReplicaManager replicaManager = new ReplicaManager();
}
}
二、加載
那么什么時候會加載一個類呢?答案很簡單,當你使用到這個類的時候JVM就會去加載。示例代碼main函數(shù)是入口,會加載ClassLoadDemo.class字節(jié)碼,又因為main函數(shù)使用了ReplicaManager.class,所以繼續(xù)加載。

三、驗證
驗證這一步,是根據(jù)JVM規(guī)范,來校驗?zāi)慵虞d進來的.class文件的內(nèi)容是否符合規(guī)范。當你的.class文件被人惡意修改了,字節(jié)碼不符合JVM規(guī)范,那么JVM是沒法執(zhí)行這個字節(jié)碼的。所以.class被加載到內(nèi)存中需要驗證,通過了之后才能交給JVM來運行
四、準備
準備這一步,就是給你的class中的類分配一定的內(nèi)存空間,比如ClassLoadDemo類,就會給它分配內(nèi)存空間,然后給它里面的static變量分配內(nèi)存空間,給一個默認的初始值。
PS:int的默認值為0,boolean的默認值是false,引用類型的默認值為null,以此類推。
五、解析
解析這一步,實際上就是把符號引用替換為直接引用的過程。這一部分涉及JVM底層,有點復雜,所以不再深究。
以上三步,就核心就是“準備階段”。因為這個階段是給加載進來的類分配好了內(nèi)存空間,類變量也分配了內(nèi)存空間,并且給了默認的初始值,這個概念,大家心里一定要有。
六、核心階段:初始化
上面講過準備階段會給類變量分配一個內(nèi)存空間,然后給初始值。但是賦值這一段邏輯在哪里執(zhí)行呢?答案就是在初始化階段。
以上的示例代碼ClassLoadDemo.class的count變量在準備階段就是給一個默認值0,但是到了初始化就會賦值為666。
知道了類的加載過程,那么什么時候初始化一個類呢?這里有一個非常重要的規(guī)則,就是如果初始化一個類,發(fā)現(xiàn)他的父類還沒初始化,那么必須先初始化他的父類。
到這里大家應(yīng)該對類加載的整個過程都有一定的了解,我再根據(jù)以上內(nèi)容畫一個張圖方便理解。

現(xiàn)在相信大家已經(jīng)搞明白了整個類加載從觸發(fā)時機到初始化的過程了,那么還有一個重要的知識點是類加載器,接著分享。
類加載器
JVM的類加載器主要有四種,Bootstrap ClassLoader、Extension ClassLoader、Application ClassLoader,還有一個是自定義類加載器。接下來我來介紹一下他們。
啟動類加載器
Bootstrap ClassLoader主要負責加載我們在電腦上安裝的Java目錄下的核心類。比如我們安裝的JDK下就有一個lib目錄,里面放著Java最核心的類,支持著Java系統(tǒng)的運行。
擴展類加載器
Extension ClassLoader也是類似的,在我們安裝的JDK中有一個lib/ext目錄,這里面有一些類就是需要使用這個類加載器加載,支持你的Java系統(tǒng)運行。
應(yīng)用程序類加載器
Application ClassLoader負責去加載ClassPath環(huán)境變量所指定的類,其實可以大概理解為加載你寫好的Java代碼,然后這個類加載器幫我們把寫好的代碼加載到內(nèi)存中運行。
自定義類加載器
除了以上的三種類加載器,我們還可以自定義類加載器,根據(jù)自己的需求加載類。
七、雙親委派機制
JVM的類加載器是有親子層級結(jié)構(gòu),啟動類加載器是處于最上層的,擴展類加載器在第二層,第三層是應(yīng)用程序類加載器,最后一層是自定義加載器。

雙親委派機制說的是,假設(shè)你的應(yīng)用程序需要加載一個類,它會首先委派給自己的父類加載器去加載,最后到Bootstrap ClassLoader加載器。
如果最上層的類加載器加載不了,他就會下推權(quán)利給下面的類加載去加載,一層層下來。
八、總結(jié)
今天分享了類加載過程還有類加載器的相關(guān)知識,主要以我的學習理解還有圖來更加直觀的理解這個知識點。
希望以上的內(nèi)容對你們有所幫助。
到此這篇關(guān)于JVM的類加載過程詳細說明的文章就介紹到這了,更多相關(guān)JVM類加載內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
IntelliJ IDEA 報錯:找不到包或者找不到符號的問題及解決方案
這篇文章主要介紹了IntelliJ IDEA 報錯:找不到包或者找不到符號的問題及解決方案,本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-08-08
Java異常:java.net.UnknownHostException產(chǎn)生的原因和解決方案
這篇文章主要給大家介紹了關(guān)于Java異常:java.net.UnknownHostException產(chǎn)生的原因和解決方案,這個異常是java.net包中的一部分,具體說它是類的一個實例,異常通常是由主機名無法解析為IP地址引起的,文中將解決的辦法介紹的非常詳細,需要的朋友可以參考下2024-01-01
解決springboot集成rocketmq關(guān)于tag的坑
這篇文章主要介紹了解決springboot集成rocketmq關(guān)于tag的坑,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-08-08

