Java虛擬機(jī):類加載機(jī)制
- 作者:新網(wǎng)
- 來(lái)源:新網(wǎng)
- 瀏覽:100
- 2018-04-28 17:02:56
類從被加載到虛擬機(jī)內(nèi)存中開(kāi)始,到卸載出內(nèi)存為止,它的整個(gè)生命周期包括:加載、驗(yàn)證、準(zhǔn)備、解析、初始化、使用和卸載七個(gè)階段。
<
div> 類從被加載到
虛擬機(jī)內(nèi)存中開(kāi)始,到卸載出內(nèi)存為止,它的整個(gè)生命周期包括:加載、驗(yàn)證、準(zhǔn)備、解析、初始化、使用和卸載七個(gè)階段。
加載時(shí)機(jī):
并不是所有的類在程序啟動(dòng)時(shí)即被加載,為提升效率,虛擬機(jī)通常秉承的是按需加載的原則,即需要使用到相應(yīng)的類時(shí)才加載對(duì)應(yīng)的類。具體包括如下幾個(gè)加載時(shí)機(jī):
遇到new、getstatic、putstatic、invokestatic這4條指令時(shí),如果對(duì)應(yīng)的類沒(méi)有被加載,虛擬機(jī)會(huì)首先加載對(duì)應(yīng)的類。這4條指令對(duì)應(yīng)的場(chǎng)景是:
創(chuàng)建一個(gè)實(shí)例對(duì)象
訪問(wèn)一個(gè)類的靜態(tài)變量(注意:不包括被final修飾,在編譯時(shí)已被放入常量池的變量)
執(zhí)行一個(gè)類的靜態(tài)方法
其中類加載的過(guò)程包括了加載、驗(yàn)證、準(zhǔn)備、解析、初始化五個(gè)階段。在這五個(gè)階段中,加載、驗(yàn)證、準(zhǔn)備和初始化這四個(gè)階段發(fā)生的順序是確定的,而解析階段則不一定,它在某些情況下可以在初始化階段之后開(kāi)始,這是為了支持Java語(yǔ)言的運(yùn)行時(shí)綁定(也成為動(dòng)態(tài)綁定或晚期綁定)。另外注意這里的幾個(gè)階段是按順序開(kāi)始,而不是按順序進(jìn)行或完成,因?yàn)檫@些階段通常都是互相交叉地混合進(jìn)行的,通常在一個(gè)階段執(zhí)行的過(guò)程中調(diào)用或激活另一個(gè)階段。
類加載器
(1)Bootstrap ClassLoader:用于加載/lib路徑下的類。主要加載JVM自身工作需要的類,完全由JVM自己控制,這個(gè)類不遵守雙親委派加載機(jī)制,它僅僅是一個(gè)類的加載工具,既沒(méi)有父加載器也沒(méi)有子加載器。
(2)ExtClassLoader:用于加載/lib/ext路徑下的類。這個(gè)類本身是JVM自身的一部分,但不是由JVM自身實(shí)現(xiàn)的,服務(wù)的特定目標(biāo)在
java.ext.dirs目錄下的類
(3)AppClassLoader:這個(gè)類服務(wù)java.class.path目錄下的類,即classpath路徑。
如果有需要,開(kāi)發(fā)人員還可以加入自定義的類加載器。如果我們要實(shí)現(xiàn)自己的類加載器,不管是直接繼承ClassLoader還是繼承URLclassLoaderlei ,它的父加載器都是AppClassLoader,因?yàn)椴还苷{(diào)用哪個(gè)父類構(gòu)造器,創(chuàng)建的對(duì)象都必須最終調(diào)用getSystemClassLoader()作為父類加載器,而該方法獲取的正是AppClassLoader。
如果應(yīng)用中沒(méi)有定義其他的類加載器,那么除了java.ext.dirs下的類是由ExtClassLoader來(lái)加載,其他的都是由AppClassLoader來(lái)加載。
既然存在如此多的類加載器,那么當(dāng)一個(gè)類需要加載時(shí),具體是由那個(gè)類進(jìn)行加載呢?由于所有的類加載器都遵守“雙親委派模型”,所以虛擬機(jī)在運(yùn)行期間可以保證一個(gè)類只會(huì)被加載一次。
雙親委派模型
雙親委派模型的工作過(guò)程:如果一個(gè)類加載器收到了類加載的請(qǐng)求,它會(huì)把這個(gè)請(qǐng)求交給自己的父類加載器去完成,父類加載器也會(huì)繼續(xù)上自己的父類加載器發(fā)送請(qǐng)求,依次類推。如果父類已經(jīng)加載過(guò)該類,則當(dāng)前加載器會(huì)直接返回已加載的類,只有當(dāng)父類沒(méi)有加載過(guò)該類時(shí),當(dāng)前類加載器才會(huì)真正去加載該類。