JVM類加載過程最全詳解(五大過程圖解)
JVM類加載
整個過程如下圖所示:
圖片
加載
加載階段是類加載的第一步,它的主要任務(wù)是找到并加載類的字節(jié)碼文件。
在加載階段,JVM會查找并加載類的字節(jié)碼文件,這個過程通常從類路徑(Classpath)中查找類文件,然后將它們讀入內(nèi)存。
如下圖所示:
圖片
JVM通過類加載器(ClassLoader)從類路徑(Classpath)中查找類文件。
加載后的類字節(jié)碼被存儲在方法區(qū)(在JVM規(guī)范中被稱為Metaspace)中,并為每個類創(chuàng)建一個Class對象。
驗證
一旦類被加載到內(nèi)存中,JVM會對字節(jié)碼文件進行驗證,以確保其完整性和合法性。
如下圖所示:
圖片
這包括檢查字節(jié)碼文件的結(jié)構(gòu),以防止惡意代碼或錯誤的字節(jié)碼文件,確保加載的類符合JVM規(guī)范,不會危害JVM的安全。
驗證主要分為3個步驟:
1.文件格式驗證
在這個階段,JVM首先檢查字節(jié)碼文件的格式是否合法。
這包括檢查文件頭是否以魔數(shù)開頭(通常為0xCAFEBABE),以及文件版本號是否合適。
2.語義驗證 在這個階段
JVM會對字節(jié)碼進行語義分析,確保代碼中不會存在語法錯誤和語義錯誤。
3.字節(jié)碼驗證 在這個階段
字節(jié)碼驗證是最復雜的一步,它檢查字節(jié)碼是否符合Java語言規(guī)范。
這包括驗證操作碼是否合法,跳轉(zhuǎn)指令是否正確,以及棧操作是否匹配。
如果字節(jié)碼驗證失敗,JVM會認為這個類是不安全的,并拒絕加載它。
準備
Java虛擬機的類準備階段是類加載過程的重要步驟之一,它負責為類的靜態(tài)變量分配內(nèi)存并初始化這些變量。
如下圖所示:
圖片
準備階段為類的靜態(tài)變量分配內(nèi)存,并初始化這些變量為默認值(通常為零值,例如0或null)。
例如,對于以下代碼:
public class MyClass {
public static int x = 10;
}
在準備階段,x 的值將被初始化為 10。
解析
解析階段的主要任務(wù):是將類或接口中的符號引用轉(zhuǎn)化為直接引用。
如下圖所示:
圖片
解析過程包括以下步驟:
a. 根據(jù)符號引用的類名找到對應(yīng)的類。
b. 驗證類的可訪問性和繼承關(guān)系,確保訪問不會違反訪問控制規(guī)則。
c. 找到符號引用對應(yīng)的字段或方法,獲取其內(nèi)存地址或偏移量。
d. 最終將符號引用替換為直接引用,以便在運行時直接訪問類、字段或方法。
初始化
初始化階段是類加載的最后一步,它負責執(zhí)行類的初始化代碼。
在初始化階段,靜態(tài)代碼塊會被執(zhí)行,靜態(tài)變量會被賦予初始值。
如下圖所示:
圖片
在初始化階段中,JVM會執(zhí)行以下操作:
1.為類的靜態(tài)變量分配內(nèi)存,并設(shè)置初始值
在加載階段中,JVM會為類的靜態(tài)變量分配內(nèi)存,并設(shè)置默認初始值。
2.執(zhí)行類的靜態(tài)代碼塊
在初始化階段中,JVM會執(zhí)行類的靜態(tài)代碼塊,這些靜態(tài)代碼塊中可以包含任意的Java代碼。
總之:JVM的類加載過程包括加載、驗證、準備、解析和初始化五個階段,確保類在被使用之前被正確加載和初始化。