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