三個主要階段:加載奇瘦、連接(驗證矫夷、準備、解析)、初始化
1. 加載
將字節(jié)碼從不同的數(shù)據(jù)源(class文件宋距、jar包窝趣、網(wǎng)絡(luò))轉(zhuǎn)化為二進制字節(jié)流加載到內(nèi)存中,并生成一個代表該類的java.lang.Class對象。此過程由類加載器完成觅赊。
2. 連接
2.1 驗證:
- 目地是為了確保Class文件的字節(jié)流中包含的信息符合當前虛擬機的要求,并且不會危害虛擬機自身的安全琼稻。
- 包括:文件格式驗證(是否以魔數(shù)oxcafebabe開頭)吮螺、元數(shù)據(jù)驗證、字節(jié)碼驗證和符號引用驗證
- 可以考慮使用
-Xverify:none
參數(shù)來關(guān)閉大部分的類驗證措施帕翻,縮短虛擬機類加載的時間
2.2 準備:
JVM會再該階段對靜態(tài)變量鸠补,分配內(nèi)存并默認初始化(對應(yīng)數(shù)據(jù)類型的默認初始值,如0嘀掸、0L紫岩、null、false等)横殴。這些變量所使用的內(nèi)存都將在方法區(qū)中進行分配
2.3 解析:
虛擬機將常量池內(nèi)的符號引用替換為直接引用的過程
3. 初始化
- 到初始化階段被因,才真正開始執(zhí)行類中定義的Java程序代碼,此階段是執(zhí)行<clinit>()方法的過程衫仑。
- <clinit>()方法是由編譯器按語句在源文件中出現(xiàn)的順序梨与,依次自動收集類中的所有靜態(tài)變量的賦值動作和靜態(tài)代碼塊中的語句,并進行合并
- 虛擬機會保證一個類的<clinit>()方法在多線程環(huán)境中被正確地加鎖文狱、同步粥鞋,如果多個線程同時區(qū)初始化一個類,那么只會有一個線程區(qū)執(zhí)行這個類的<clinit>()方法瞄崇,其它線程都需要阻塞等待呻粹,知道活動線程執(zhí)行<clinit>()方法完畢