Java類加載過(guò)程

類從被加載到JVM中開(kāi)始两蟀,到卸載為止网梢,整個(gè)生命周期包括:加載、驗(yàn)證赂毯、準(zhǔn)備战虏、解析、初始化党涕、使用和卸載七個(gè)階段烦感。

其中類加載過(guò)程包括加載、驗(yàn)證膛堤、準(zhǔn)備手趣、解析和初始化五個(gè)階段。




(1)類加載器的任務(wù)就是根據(jù)一個(gè)類的全限定名來(lái)讀取此類的二進(jìn)制字節(jié)流到JVM中肥荔,然后轉(zhuǎn)換為一個(gè)與目標(biāo)類對(duì)應(yīng)的java.lang.Class對(duì)象實(shí)例绿渣。BootstrapClassLoader、ExtClassLoader和AppClassLoaderdefineClass方法將字節(jié)碼的byte數(shù)組轉(zhuǎn)換為一個(gè)類的class對(duì)象實(shí)例燕耿,如果希望在類被記載到JVM時(shí)就被鏈接中符,那么可以調(diào)用resolveClass方法。

(2)自定義類加載器需要繼承抽象類ClassLoader誉帅,實(shí)現(xiàn)findClass方法淀散,該方法會(huì)在loadClass調(diào)用的時(shí)候被調(diào)用,findClass默認(rèn)會(huì)拋出異常蚜锨。findClass方法表示根據(jù)類名查找類對(duì)象档插,loadClass方法表示根據(jù)類名進(jìn)行雙親委托模型進(jìn)行類加載并返回類對(duì)象,defineClass方法表示跟根據(jù)類的字節(jié)碼轉(zhuǎn)換為類對(duì)象

雙親委托模型亚再,約定類加載器的加載機(jī)制:


(1)當(dāng)一個(gè)類加載器接收到一個(gè)類加載的任務(wù)時(shí)郭膛,不會(huì)立即展開(kāi)加載,而是將加載任務(wù)委托給它的父類加載器去執(zhí)行氛悬,每一層的類都采用相同的方式则剃,直至委托給最頂層的啟動(dòng)類加載器為止凄诞。如果父類加載器無(wú)法加載委托給它的類,便將類的加載任務(wù)退回給下一級(jí)類加載器去執(zhí)行加載忍级。

(2)使用雙親委托機(jī)制的好處是:能夠有效確保一個(gè)類的全局唯一性帆谍,當(dāng)程序中出現(xiàn)多個(gè)限定名相同的類時(shí),類加載器在執(zhí)行加載時(shí)轴咱,始終只會(huì)加載其中的某一個(gè)類汛蝙。

(3)使用雙親委托模型來(lái)組織類加載器之間的關(guān)系,有一個(gè)顯而易見(jiàn)的好處就是Java類隨著它的類加載器一起具備了一種帶有優(yōu)先級(jí)的層次關(guān)系朴肺。例如類java.lang.Object窖剑,它存放在rt.jar之中,無(wú)論哪一個(gè)類加載器要加載這個(gè)類戈稿,最終都是委托給處于模型最頂端的啟動(dòng)類加載器進(jìn)行加載西土,因此Object類在程序的各種加載器環(huán)境中都是同一個(gè)類。相反鞍盗,如果沒(méi)有使用雙親委托模型需了,由各個(gè)類加載器自行去加載的話,如果用戶自己編寫(xiě)了一個(gè)稱為java.lang.Object的類般甲,并放在程序的ClassPath中肋乍,那系統(tǒng)中將會(huì)出現(xiàn)多個(gè)不同的Object類,Java類型體系中最基礎(chǔ)的行為也就無(wú)法保證敷存,應(yīng)用程序也將會(huì)變得一片混亂墓造。如果自己去編寫(xiě)一個(gè)與rt.jar類庫(kù)中已有類重名的Java類,將會(huì)發(fā)現(xiàn)可以正常編譯锚烦,但永遠(yuǎn)無(wú)法被加載運(yùn)行觅闽。

(4)雙親委托模型對(duì)于保證Java程序的穩(wěn)定運(yùn)作很重要,但它的實(shí)現(xiàn)卻非常簡(jiǎn)單涮俄,實(shí)現(xiàn)雙親委托的代碼都集中在java.lang.ClassLoader的loadClass()方法中蛉拙,邏輯清晰易懂:先檢查是否已經(jīng)被加載過(guò),若沒(méi)有加載則調(diào)用父類加載器的loadClass()方法禽拔,若父加載器為空則默認(rèn)使用啟動(dòng)類加載器作為父加載器刘离。如果父類加載器加載失敗室叉,拋出ClassNotFoundException異常后睹栖,再調(diào)用自己的findClass方法進(jìn)行加載。


1茧痕、加載

簡(jiǎn)單的說(shuō)野来,類加載階段就是由類加載器負(fù)責(zé)根據(jù)一個(gè)類的全限定名來(lái)讀取此類的二進(jìn)制字節(jié)流到JVM內(nèi)部,并存儲(chǔ)在運(yùn)行時(shí)內(nèi)存區(qū)的方法區(qū)踪旷,然后將其轉(zhuǎn)換為一個(gè)與目標(biāo)類型對(duì)應(yīng)的java.lang.Class對(duì)象實(shí)例(Java虛擬機(jī)規(guī)范并沒(méi)有明確要求一定要存儲(chǔ)在堆區(qū)中曼氛,只是hotspot選擇將Class對(duì)戲那個(gè)存儲(chǔ)在方法區(qū)中)豁辉,這個(gè)Class對(duì)象在日后就會(huì)作為方法區(qū)中該類的各種數(shù)據(jù)的訪問(wèn)入口。

2舀患、鏈接

鏈接階段要做的是將加載到JVM中的二進(jìn)制字節(jié)流的類數(shù)據(jù)信息合并到JVM的運(yùn)行時(shí)狀態(tài)中徽级,經(jīng)由驗(yàn)證、準(zhǔn)備和解析三個(gè)階段聊浅。

1)餐抢、驗(yàn)證

驗(yàn)證類數(shù)據(jù)信息是否符合JVM規(guī)范,是否是一個(gè)有效的字節(jié)碼文件低匙,驗(yàn)證內(nèi)容涵蓋了類數(shù)據(jù)信息的格式驗(yàn)證旷痕、語(yǔ)義分析、操作驗(yàn)證等顽冶。

格式驗(yàn)證:驗(yàn)證是否符合class文件規(guī)范

語(yǔ)義驗(yàn)證:檢查一個(gè)被標(biāo)記為final的類型是否包含子類欺抗;檢查一個(gè)類中的final方法視頻被子類進(jìn)行重寫(xiě);確保父類和子類之間沒(méi)有不兼容的一些方法聲明(比如方法簽名相同强重,但方法的返回值不同)

操作驗(yàn)證:在操作數(shù)棧中的數(shù)據(jù)必須進(jìn)行正確的操作绞呈,對(duì)常量池中的各種符號(hào)引用執(zhí)行驗(yàn)證(通常在解析階段執(zhí)行,檢查是否通過(guò)富豪引用中描述的全限定名定位到指定類型上间景,以及類成員信息的訪問(wèn)修飾符是否允許訪問(wèn)等)


3)报强、解析將常量池中的符號(hào)引用轉(zhuǎn)為直接引用(得到類或者字段、方法在內(nèi)存中的指針或者偏移量拱燃,以便直接調(diào)用該方法)秉溉,這個(gè)可以在初始化之后再執(zhí)行。

可以認(rèn)為是一些靜態(tài)綁定的會(huì)被解析碗誉,動(dòng)態(tài)綁定則只會(huì)在運(yùn)行是進(jìn)行解析召嘶;靜態(tài)綁定包括一些final方法(不可以重寫(xiě)),static方法(只會(huì)屬于當(dāng)前類),構(gòu)造器(不會(huì)被重寫(xiě))

3哮缺、初始化

將一個(gè)類中所有被static關(guān)鍵字標(biāo)識(shí)的代碼統(tǒng)一執(zhí)行一遍弄跌,如果執(zhí)行的是靜態(tài)變量,那么就會(huì)使用用戶指定的值覆蓋之前在準(zhǔn)備階段設(shè)置的初始值尝苇;如果執(zhí)行的是static代碼塊铛只,那么在初始化階段,JVM就會(huì)執(zhí)行static代碼塊中定義的所有操作糠溜。

所有類變量初始化語(yǔ)句和靜態(tài)代碼塊都會(huì)在編譯時(shí)被前端編譯器放在收集器里頭淳玩,存放到一個(gè)特殊的方法中,這個(gè)方法就是方法非竿,即類/接口初始化方法蜕着。該方法的作用就是初始化一個(gè)中的變量,使用用戶指定的值覆蓋之前在準(zhǔn)備階段里設(shè)定的初始值红柱。任何invoke之類的字節(jié)碼都無(wú)法調(diào)用方法承匣,因?yàn)樵摲椒ㄖ荒茉陬惣虞d的過(guò)程中由JVM調(diào)用蓖乘。

如果父類還沒(méi)有被初始化,那么優(yōu)先對(duì)父類初始化韧骗,但在方法內(nèi)部不會(huì)顯示調(diào)用父類的方法嘉抒,由JVM負(fù)責(zé)保證一個(gè)類的方法執(zhí)行之前,它的父類方法已經(jīng)被執(zhí)行袍暴。

JVM必須確保一個(gè)類在初始化的過(guò)程中众眨,如果是多線程需要同時(shí)初始化它,僅僅只能允許其中一個(gè)線程對(duì)其執(zhí)行初始化操作容诬,其余線程必須等待娩梨,只有在活動(dòng)線程執(zhí)行完對(duì)類的初始化操作之后,才會(huì)通知正在等待的其他線程览徒。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末狈定,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子习蓬,更是在濱河造成了極大的恐慌纽什,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,270評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件躲叼,死亡現(xiàn)場(chǎng)離奇詭異芦缰,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)枫慷,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)让蕾,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人或听,你說(shuō)我怎么就攤上這事探孝。” “怎么了誉裆?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,630評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵顿颅,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我足丢,道長(zhǎng)粱腻,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,906評(píng)論 1 295
  • 正文 為了忘掉前任斩跌,我火速辦了婚禮绍些,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘滔驶。我一直安慰自己遇革,他們只是感情好卿闹,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,928評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布揭糕。 她就那樣靜靜地躺著萝快,像睡著了一般。 火紅的嫁衣襯著肌膚如雪著角。 梳的紋絲不亂的頭發(fā)上揪漩,一...
    開(kāi)封第一講書(shū)人閱讀 51,718評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音吏口,去河邊找鬼奄容。 笑死,一個(gè)胖子當(dāng)著我的面吹牛产徊,可吹牛的內(nèi)容都是我干的昂勒。 我是一名探鬼主播,決...
    沈念sama閱讀 40,442評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼舟铜,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼戈盈!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起谆刨,我...
    開(kāi)封第一講書(shū)人閱讀 39,345評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤塘娶,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后痊夭,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體刁岸,經(jīng)...
    沈念sama閱讀 45,802評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,984評(píng)論 3 337
  • 正文 我和宋清朗相戀三年她我,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了虹曙。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,117評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡番舆,死狀恐怖根吁,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情合蔽,我是刑警寧澤击敌,帶...
    沈念sama閱讀 35,810評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站拴事,受9級(jí)特大地震影響沃斤,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜刃宵,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,462評(píng)論 3 331
  • 文/蒙蒙 一衡瓶、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧牲证,春花似錦哮针、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,011評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)等太。三九已至,卻和暖如春蛮放,著一層夾襖步出監(jiān)牢的瞬間缩抡,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,139評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工包颁, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留瞻想,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,377評(píng)論 3 373
  • 正文 我出身青樓娩嚼,卻偏偏與公主長(zhǎng)得像蘑险,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子岳悟,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,060評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容