<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Java虛擬機(jī)探險(xiǎn)之Class Loader

    Posted on 2010-08-17 10:47 天快黑了 閱讀(2230) 評(píng)論(0)  編輯  收藏 所屬分類: JVM
     

    眾所周知,所有的Java class文件都是由JVM(虛擬機(jī))加載并執(zhí)行的。深入理解JVM對(duì)于我們提高Java技術(shù)和解決Java問題都有非常大的幫助。

    JVM內(nèi)部主要包括內(nèi)存管理和Class Loader(類加載器)兩個(gè)部分。熟悉了內(nèi)存管理,我們就會(huì)清楚程序在內(nèi)存中是怎么分配和執(zhí)行的,就能解決所有和對(duì)象相關(guān)的問題(比如Memory Leak)。理解了Class Loader,就能解決所有類找不到(比如遇到NoClassDefFoundErrorClassNotFoundException)或配置文件找不到問題。

    這次我們只討論JVMClass Loader,下次再討論JVM的內(nèi)存管理。

    Class Loader的主要作用就是負(fù)責(zé)查找類并將其加載到內(nèi)存中。有趣的是,Java中的Class Loader也是由Java所寫,就和普通的class一樣。這就產(chǎn)生了一個(gè)是雞生蛋還是蛋生雞的問題,到底第一個(gè)class由誰來加載呢?我們稍后會(huì)來討論這個(gè)問題。

    先來看一下Class Loader所具有的特點(diǎn)。

    1.       繼承關(guān)系

    雖然Class Loader也是一個(gè)Java class,但這里的繼承不是指定義class時(shí)使用的extends關(guān)鍵字來實(shí)現(xiàn)的繼承,而是指由屬性來維持的繼承關(guān)系。即通過Class Loader的構(gòu)造方法或其它方法顯式的設(shè)置一個(gè)父Class Loader

    2.       代理關(guān)系

    每一個(gè)Class Loader在接到請(qǐng)求去加載一個(gè)類之前(默認(rèn),訪問一個(gè)類的時(shí)候,就會(huì)由加載當(dāng)前類的Class Loader去加載被訪問的類),它會(huì)首先請(qǐng)求它的父Class Loader來嘗試加載,依次往上,如果父Class Loader加載成功,則直接返回,子Class Loader不再查找。

    否則依次往下查找并加載。如果直到被請(qǐng)求的Class Loader也沒有找到要加載的類,則會(huì)出現(xiàn)NoClassDefFoundErrorClassNotFoundException

    當(dāng)然如果被請(qǐng)求的類已經(jīng)加載到了內(nèi)存中,就不會(huì)觸發(fā)這個(gè)查找過程了,而是直接返回已經(jīng)加載的類。

    我們來看一個(gè)例子,假設(shè)有圖1中的Class Loader層次:


    如果我們請(qǐng)求
    Class Loader E去加載Test.class,首先它會(huì)請(qǐng)求父Class Loader D去嘗試加載。同樣Class Loader D會(huì)先請(qǐng)求它的父Class Loader C去嘗試加載Test.class。當(dāng)然這里Class Loader C找不到Test.class,于是轉(zhuǎn)回由Class Loader D去加載。最終Class Loader D成功找到了D:"Test.class,并將其加載到內(nèi)存中。

    同樣,如果我們請(qǐng)求Class Loader F去加載Test3.classClass Loader CClass Loader D在各自的搜索范圍內(nèi)都找不到Test3.class。最終會(huì)由Class Loader F自己加載F:"Test3.class到內(nèi)存中。

    如果我們請(qǐng)求Class Loader D去加載Test3.class,最終就會(huì)出現(xiàn)NoClassDefFoundErrorClassNotFoundException

    3.       同一繼承鏈可見性

    在同一個(gè)Class Loader對(duì)象的繼承鏈中,下面被加載的類可以訪問上面被加載的類,反之則不可以。

    同樣以圖1為例,Test4.class可以訪問到D:"Test.classC:"Test2.class

    而如果D:"Test.classC:"Test2.class嘗試訪問Test4.class,就會(huì)出現(xiàn)NoClassDefFoundErrorClassNotFoundException

    4.       多個(gè)繼承鏈不可見性

    多個(gè)繼承鏈之間彼此看不到對(duì)方,不能相互訪問。

    還以圖1為例,如果Test4.class訪問Test3.class,或反過來Test3.class訪問Test4.class,都會(huì)引起NoClassDefFoundErrorClassNotFoundException

    理解了Class Loader所具有的特點(diǎn),我們來看看JDK中都預(yù)置了哪些Class Loader。也是JVM啟動(dòng)時(shí)默認(rèn)創(chuàng)建的Class Loader。如圖2


    通過圖
    2,我們可以看到Bootstrap Class LoaderJVM中的祖先Class Loader。它是JDK中唯一一個(gè)由C++所寫的Class Loader,它負(fù)責(zé)加載JDK的核心類庫(rt.jar)以及另外兩個(gè)由Java所寫的Class LoaderExt Class LoaderApp Class Loader)。之后就功成身退,轉(zhuǎn)由Ext Class LoaderApp Class Loader加載所有應(yīng)用中用到的類。

    一般我們的應(yīng)用都是通過設(shè)置CLASSPATH,最終由App Class Loader來加載。根據(jù)Class Loader的繼承關(guān)系,我們應(yīng)用中的類可以訪問JDK的核心類庫。反之則會(huì)出錯(cuò)。

    我們?cè)賮砜纯?/span>WebLogicClass Loader的層次關(guān)系(如圖4)。如果需要,大家可以參考一下WebLogicWAREAR的文件結(jié)構(gòu)(如圖3




    WLS
    中自定義了很多新的Class Loader,當(dāng)然他們的祖先Class Loader都是JDK中的App (or System) Class Loader。我們來看一下每個(gè)Class Loader的職責(zé)。

    1.       JDK App (or System) Class Loader

    l       負(fù)責(zé)加載WLS啟動(dòng)腳本中CLASSPATH中設(shè)置的類

    l       所有的類都會(huì)最先由它嘗試加載

    l       因?yàn)?/span>CLASSPATH的值在運(yùn)行期不允許修改,所以由該Class Loader加載的類在運(yùn)行期不能被動(dòng)態(tài)卸載(替換)

    2.       EJB Class Loader (1)

    l       負(fù)責(zé)加載單獨(dú)的EJB jar里的類。

    l       不同的EJB jar文件會(huì)被不同實(shí)例的Class Loader加載,因此EJB jar彼此之間互相看不到對(duì)方

    3.       WAR Class Loader (1)

    l       負(fù)責(zé)加載單獨(dú)的WAR里的類

    l       不同的WAR文件會(huì)被不同實(shí)例的Class Loader加載,因此WAR彼此之間互相看不到對(duì)方

    4.       EAR Class Loader

    l       負(fù)責(zé)加載EAR里面的APP-INF下的類

    l       不同的EAR文件會(huì)被不同實(shí)例的EAR Class Loader加載,因此EAR彼此之間互相看不到對(duì)方

    l       它下面有一個(gè)EJB Class Loader (2) 實(shí)例,負(fù)責(zé)加載EAR里面所有的EJB jar。因此,EAR中的EJB彼此之間可以看到對(duì)方

    l       EJB Class Loader (2) 下有多個(gè)WAR Class Loader (2) 實(shí)例。每個(gè)實(shí)例負(fù)責(zé)加載EAR里面的一個(gè)WAR。所以,EAR中的WAR彼此之間看不到對(duì)方

    l       根據(jù)繼承鏈規(guī)則,WAR可以看到所有的EJBAPP-INF下的所有類。 EJB可以看到APP-INF下的所有類,但反之則不可以

    Class Loader雖然稱為類加載器,但并不意味著只能用來加載Class,我們還可以利用它來查找圖片和配置文件等資源。比如,我們經(jīng)常使用getClass().getResourceAsStream(name)來查找配置文件。同樣,查找其它資源文件的方式和上面一樣,也會(huì)先請(qǐng)求父Class Loader來負(fù)責(zé)查找。

    這里,我們只簡(jiǎn)單介紹了Class Loader對(duì)于類的查找,而關(guān)于Class Loader的具體加載、校驗(yàn)和初始化的過程,感興趣的朋友可以參考《深入Java虛擬機(jī)》


    只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


    網(wǎng)站導(dǎo)航:
     

    posts - 5, comments - 25, trackbacks - 0, articles - 1

    Copyright © 天快黑了

    主站蜘蛛池模板: 亚洲精品国产电影午夜| 国产精品永久免费| 一个人免费播放在线视频看片| 97公开免费视频| 国产成人高清亚洲| 亚洲大码熟女在线观看| 国产一级片免费看| 亚洲精品视频免费| 特级aa**毛片免费观看| 在线免费不卡视频| 亚洲国产理论片在线播放| **毛片免费观看久久精品| 亚洲国产精品无码AAA片| 9久热这里只有精品免费| 四虎永久免费地址在线观看| 亚洲中文字幕日本无线码| 青青草a免费线观a| 亚洲美女视频网址| 69视频免费观看l| 羞羞漫画登录页面免费 | 亚洲一区中文字幕在线电影网| 日本人成在线视频免费播放| 亚洲国产精品VA在线看黑人| 成人男女网18免费视频| 污污免费在线观看| 亚洲日韩在线第一页| 免费大片黄在线观看yw| 爽爽爽爽爽爽爽成人免费观看| 亚洲国产美女精品久久久久∴| 日韩人妻一区二区三区免费| 亚洲va久久久久| 亚洲第一成人影院| 国产精品免费久久久久电影网| 亚洲日韩AV一区二区三区四区| 亚洲成A人片在线观看无码3D| 国产精品入口麻豆免费观看| 亚洲精品无码久久久久YW| 久久精品国产亚洲77777| 成人网站免费观看| 一级做a爰全过程免费视频毛片| 77777亚洲午夜久久多喷|