今天遇到一個面試題缝呕,類的加載過程誓竿,感覺自己回答的一團糟贺辰,完全沒有概念煎殷,那我今天還是一定要把這個整理一下
看下流程圖(結(jié)構(gòu)化思維)
5個大階段:
加載--》鏈接--》初始化--》使用--》卸載
7個小階段:(鏈接1拆3)
加載--》驗證--》準備--》解析--》初始化--》使用--》卸載
①加載
JVM把class字節(jié)碼加載到內(nèi)存蔼卡,將這些字節(jié)碼轉(zhuǎn)化成方法區(qū)中的運行時數(shù)據(jù)(靜態(tài)變量喊崖,靜態(tài)代碼塊,常量池等)
在堆中生產(chǎn)一個class的對象雇逞,通過反射機制荤懂,通過這個對象可以訪問到方法區(qū)對應的數(shù)據(jù)
②鏈接(驗證,準備塘砸,解析)
驗證:確保加載的類信息符合jvm規(guī)范节仿,沒有安全方面的問題
準備:為類變量(static)生成內(nèi)存空間,并設(shè)置初始值(只是設(shè)置初始值掉蔬,區(qū)別一下初始化階段做的事)
解析:常量池中的符號引用改為直接引用(地址引用)廊宪,主要包括四種類型引用的解析。類或接口的解析女轿、字段解析箭启、方法解析、接口方法解析蛉迹。
解析階段是虛擬機將常量池內(nèi)的符號引用替換為直接引用的過程傅寡。
二者之間的關(guān)聯(lián)如下
符號引用(Symbolic Reference):符號引用以一組符號來描述所引用的目標,符號可以是任何形式的字面量北救,只要使用時能無歧義的定位到目標就行荐操,符號引用與虛擬機的內(nèi)存布局沒有關(guān)系,引用的目標不一定需要已經(jīng)加載到內(nèi)存中珍策。種種虛擬機的內(nèi)存布局可以都不相同淀零。但是他們能接受的符號引用必須是一致的。符號引用的字面量形式明確定義在JAVA虛擬機規(guī)范的Class文件中膛壹。
直接引用(Direct Reference):直接引用是直接指向目標的指針驾中、相對偏移量或是一個能間接定位到目標的句柄。直接引用是和虛擬機實現(xiàn)的內(nèi)存布局相關(guān)的模聋,同一個符號引用在不同虛擬機實例上翻譯出來的直接引用一般不會相同肩民,如果有了直接引用,那引用的目標必定在內(nèi)存中存在链方。
③初始化
執(zhí)行類構(gòu)造器<clinit>的過程持痰。
類構(gòu)造器<clinit>方法是由編譯器自動收集類變量的賦值動作和靜態(tài)語句塊中的語句合并生成的代碼塊。
注意:
a.如果發(fā)現(xiàn)父類沒有初始化祟蚀,先初始化父類
b.虛擬機會保障<clinit>在多線程下正確的加鎖和同步