Java類生命周期圖
加載
- 通過一個(gè)類的全限定名來獲取此類的二進(jìn)制字節(jié)流
- 將這個(gè)字節(jié)流所代表的靜態(tài)存儲(chǔ)結(jié)構(gòu)轉(zhuǎn)化為方法區(qū)的運(yùn)行時(shí)數(shù)據(jù)結(jié)構(gòu)
- 在java堆中生成一個(gè)代表這個(gè)類的Class對(duì)象,作為方法區(qū)這些數(shù)據(jù)的訪問入口
連接
驗(yàn)證
- 驗(yàn)證是為了確保Class文件的字節(jié)流中包含的信息符合當(dāng)前虛擬機(jī)的要求屑墨,并且不會(huì)危害虛擬機(jī)自身的安全
- 包括文件格式驗(yàn)證敛熬、元數(shù)據(jù)驗(yàn)證枚尼、字節(jié)碼驗(yàn)證庭惜、符號(hào)引用驗(yàn)證
準(zhǔn)備
- 類變量分配內(nèi)存院峡,并設(shè)為jvm默認(rèn)的初始值
解析
- 將常量池內(nèi)的符號(hào)引用替換為直接引用的過程
- 主要針對(duì)類或接口嚎莉、字段关拒、類方法、接口方法四類符號(hào)引用進(jìn)行解析
- 符號(hào)引用
- 以一組符號(hào)來描述所引用的目標(biāo)蝉揍,符號(hào)可以是任何形式的字面量牢撼,只要使用時(shí)能無歧義地定位到目標(biāo)即可。符號(hào)引用與虛擬機(jī)實(shí)現(xiàn)的內(nèi)存布局無關(guān)疑苫,引用的目標(biāo)并不一定已經(jīng)加載到內(nèi)存中
- 直接引用
- 可以是直接指向目標(biāo)的指針、相對(duì)偏移量或者一個(gè)能間接定位到目標(biāo)的句柄纷责。如果有了直接引用捍掺,那引用的目標(biāo)必定已經(jīng)在內(nèi)存中存在。
初始化
- 初始化階段是執(zhí)行類構(gòu)造器clinit方法的過程
- clinit方法
- 由編譯器自動(dòng)收集所有類變量(靜態(tài)非final) 賦值操作和靜態(tài)代碼塊語句合并產(chǎn)生
- 收集順序由出現(xiàn)順序決定再膳,定義在前面的不能訪問定義在后面的類變量
- 虛擬機(jī)保證父類clinit方法先于子類clinit方法執(zhí)行
- 類或接口不一定都有clinit方法
- 虛擬機(jī)保證clinit方法在多線程環(huán)境下被正確的加鎖和同步
- 時(shí)機(jī)
- new挺勿、操作該類類變量、調(diào)用類方法
- 對(duì)類反射
- 子類初始化的時(shí)候喂柒,父類還沒有初始化不瓶,則會(huì)先進(jìn)行父類初始化
- main函數(shù)對(duì)應(yīng)的類
使用
參考對(duì)象生命周期
卸載
jvm回收條件
- 該類所有的實(shí)例都已經(jīng)被回收
- 加載該類的ClassLoader已經(jīng)被回收
- Class對(duì)象沒有任何地方被引用禾嫉,且無法在任何地方通過反射訪問該類的方法