JVM學(xué)習(xí)筆記(一)

一.Java有兩種類型的類加載器薪夕。

1.Java虛擬機(jī)自帶的加載器。

①根(Bootstrap)類加載器:它用來加載 Java 的核心庫叭披,如java.lang.*等寥殖,它的父加載器為null玩讳。根類加載器從系統(tǒng)屬性sun.boot.class.path所指定的目錄中加載類涩蜘,根類加載器的實(shí)現(xiàn)依賴于底層操作系統(tǒng)嚼贡,屬于虛擬機(jī)實(shí)現(xiàn)的一部分,是用原生代碼來實(shí)現(xiàn)的同诫,是用C/C++編寫粤策,并不繼承自java.lang.ClassLoader。

②擴(kuò)展(Extension)類加載器: 它的父類加載器為根類加載器误窖,它用來加載 Java 的擴(kuò)展庫叮盘,它從java.ext.dirs系統(tǒng)屬性所指定的目錄中加載類,或者從JDK的安裝目錄的jre\lib\ext子目錄(擴(kuò)展目錄)下加載類霹俺。Java 虛擬機(jī)的實(shí)現(xiàn)會(huì)提供一個(gè)擴(kuò)展庫目錄柔吼,如果用戶創(chuàng)建的jar文件放在這個(gè)目錄下,該類加載器在此目錄里面查找并加載 Java 類丙唧,擴(kuò)展類加載器是用純java編寫的愈魏,是java.lang.ClassLoader子類。

③系統(tǒng)(System)類加載器:它也叫應(yīng)用加載器想际,它的父類加載器為擴(kuò)展類加載器培漏,它根據(jù) java 應(yīng)用的類路徑(CLASSPATH)或者系統(tǒng)屬性java.class.path所指定的目錄中來加載 Java 類,他是用戶自定義類加載器的默認(rèn)父加載器胡本,一般來說牌柄,Java應(yīng)用的類都是由它來完成加載,可以通過ClassLoader.getSystemClassLoader()來獲取侧甫。系統(tǒng)類加載器是用純java編寫珊佣,是java.lang.ClassLoader類的子類。

注意:java的系統(tǒng)屬性以及加載目錄代碼測試查找披粟。

jvm系統(tǒng)屬性

2.用戶自定義的類加載器彩扔。

用戶編寫自定義類加載器,是需要直接或間接繼承java.lang.ClassLoader抽象類僻爽。自定義類加載器和jvm自帶加載器(根類加載器虫碉、擴(kuò)展類加載器、系統(tǒng)加載器)唯一區(qū)別是否被虛擬機(jī)默認(rèn)使用胸梆,在不指定父類加載器的情況下敦捧,默認(rèn)采用系統(tǒng)加載器。

二.類加載器的父類委托機(jī)制

JVM在加載類是默認(rèn)采用的是雙親委任機(jī)制碰镜,就是某個(gè)特定的類加載器在接到加載類的請(qǐng)求時(shí)兢卵,首先將加載任務(wù)委托給父類加載器,依次遞歸绪颖,如果父類加載器可以完成類加載任務(wù)秽荤,就成功返回;只有父類加載器無法完成此加載任務(wù)時(shí),才自己去加載窃款,如果本身類加載器也不能加載成功课兄,則拋出ClassNotFoundException異常。在父親委托機(jī)制中晨继,各個(gè)加載器按照父子關(guān)系形成了樹形結(jié)構(gòu)烟阐,除了根類加載器以外,其余的類加載器都有且只有一個(gè)父加載器紊扬。


類加載器結(jié)構(gòu)圖

1.JVM自帶類加載器的樹狀組織結(jié)構(gòu)

類加載器結(jié)構(gòu)圖

上述代碼運(yùn)行結(jié)果:


ClassLoaderTree運(yùn)行的結(jié)果

第一個(gè)輸出的是ClassLoaderTree類的類加載器蜒茄,即是系統(tǒng)類加載器,它是sun.misc.Launcher$AppClassLoader類的實(shí)例餐屎;第二個(gè)輸出的是擴(kuò)展類加載器檀葛,是sun.misc.Launcher$ExtClassLoader類的實(shí)例。需要注意的是這里沒有根類加載器腹缩,這是由于有些jdk的實(shí)現(xiàn)對(duì)于父類加載器是根類加載器的情況屿聋,getParent()方法返回null

2.自定義類加載器及其加載過程。

用戶自定義一個(gè)類加載器MyClassLoader.

自定義類加載器MyClassLoader

? ? ? ?自定義類加載器loader首先從自己的命令空間中查找A類是否已經(jīng)被加載庆聘,如果已經(jīng)加載胜臊,就直接返回代表A類的Class對(duì)象引用。如果A類沒有被加載伙判,loader首先請(qǐng)求系統(tǒng)類加載器代為加載象对,系統(tǒng)類加載器再去請(qǐng)求擴(kuò)展類代為加載,擴(kuò)展類加載器再請(qǐng)求根類加載器代為加載宴抚。如根類加載器和擴(kuò)展類加載器都不能加載勒魔,則系統(tǒng)類加載器嘗試加載,如能成功菇曲,則將A類所對(duì)應(yīng)的Class對(duì)象的引用返回給loader,從而成功將A加載進(jìn)虛擬機(jī)冠绢。如系統(tǒng)類加載器不能加載A類,則loader嘗試加載常潮。若所有的父加載器及l(fā)oader本身都不能加載弟胀,則拋出ClassNotFoundException異常。

?? ? ?若有一個(gè)類加載器能成功加載A類喊式,那么這個(gè)類加載被稱為定義類加載器孵户,所有能成功返回Class對(duì)象的引用的類加載器(包括定義類加載器)都被稱為初始類加載器。在例子中系統(tǒng)類加載器稱為定義類加載器岔留,系統(tǒng)類加載器和MyClassLoader為初始類加載器夏哭。

? ? ?注意:①?需要指出的是,加載器之間的父子關(guān)系實(shí)際上指的是加載器對(duì)象之間的包裝關(guān)系献联,而不是類之間的繼承關(guān)系竖配。一對(duì)父子加載器可能是同一個(gè)加載器類的兩個(gè)實(shí)例何址,也可能不是。在子加載器對(duì)象中包裝了一個(gè)父加載器對(duì)象进胯。如上圖例子loader和loader1都是MyClassLoader類的實(shí)例用爪,并且loader1包裝了loader,并且loader為loader1的父加載器。

? ? ? ? ? ? ②每個(gè)類加載器都有自己的命名空間龄减,命名空間由該加載器及所有父加載器所加載的類組成项钮。在同一個(gè)命名空間中班眯,不會(huì)出現(xiàn)類的完整名字(包括類的包名)相同的兩個(gè)類希停;在不同的命名空間中,由可能出現(xiàn)類的完整名字(包括類的包名)相同的兩個(gè)類署隘。

? ? ? ? ? ?③由同一類加載器加載的屬于相同包的類組成了運(yùn)行時(shí)包宠能。決定兩個(gè)類是不是屬于同一個(gè)運(yùn)行時(shí)包,不僅要看它們的包名是否相同磁餐,還要看定義類加載器是否相同违崇。只有屬于同一運(yùn)行時(shí)包的類才能互相訪問包可見(即默認(rèn)訪問級(jí)別)的類和類成員。這樣的限制能避免用戶自定義的類冒充核心類庫的類诊霹,去訪問核心類庫的包可見成員羞延。假設(shè)用戶自己定義了一個(gè)類java.lang.Spy,并由用戶自定義的類加載器加載,由于java.lang.Spy和核心類庫java.lang.*由不同的加載器加載脾还,它們屬于不同的運(yùn)行時(shí)包伴箩,所以java.lang.Spy不能訪問核心類庫java.lang包中的包可見成員。

? ? ? ?④要?jiǎng)?chuàng)建用戶自己的類加載器鄙漏,只需要擴(kuò)展java.lang.ClassLoader類嗤谚,然后覆蓋它的findClass(String name)方法即可,該方法根據(jù)參數(shù)指定的類的名字怔蚌,返回對(duì)應(yīng)的Class對(duì)象引用巩步。

? ? ? ⑤同一個(gè)命名內(nèi)的類是相互可見的。自加載器的命名空間包含所有父加載器的命名空間桦踊。因此由子類加載器的類能看見父加載器加載的類椅野。例如系統(tǒng)類加載器的類能看見根類加載器加載的類。而由父加載器加載的類不能看見自加載器加載的類籍胯。如果兩個(gè)加載器之間沒有直接或間接的父子關(guān)系竟闪,那么它們各自加載的類相互不可見。

備注:1.本學(xué)習(xí)筆記是基于張龍老師JVM課程 芒炼。

? ? ? ? 2.參考資料:http://blog.csdn.net/zhoudaxia/article/details/35824249

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末瘫怜,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子本刽,更是在濱河造成了極大的恐慌鲸湃,老刑警劉巖赠涮,帶你破解...
    沈念sama閱讀 218,386評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異暗挑,居然都是意外死亡笋除,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,142評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門炸裆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來垃它,“玉大人,你說我怎么就攤上這事烹看」矗” “怎么了?”我有些...
    開封第一講書人閱讀 164,704評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵惯殊,是天一觀的道長酱吝。 經(jīng)常有香客問我,道長土思,這世上最難降的妖魔是什么务热? 我笑而不...
    開封第一講書人閱讀 58,702評(píng)論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮己儒,結(jié)果婚禮上崎岂,老公的妹妹穿的比我還像新娘。我一直安慰自己闪湾,他們只是感情好冲甘,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,716評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著响谓,像睡著了一般损合。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上娘纷,一...
    開封第一講書人閱讀 51,573評(píng)論 1 305
  • 那天嫁审,我揣著相機(jī)與錄音,去河邊找鬼赖晶。 笑死律适,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的遏插。 我是一名探鬼主播捂贿,決...
    沈念sama閱讀 40,314評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼胳嘲!你這毒婦竟也來了厂僧?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,230評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤了牛,失蹤者是張志新(化名)和其女友劉穎颜屠,沒想到半個(gè)月后辰妙,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,680評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡甫窟,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,873評(píng)論 3 336
  • 正文 我和宋清朗相戀三年密浑,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片粗井。...
    茶點(diǎn)故事閱讀 39,991評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡尔破,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出浇衬,到底是詐尸還是另有隱情懒构,我是刑警寧澤,帶...
    沈念sama閱讀 35,706評(píng)論 5 346
  • 正文 年R本政府宣布径玖,位于F島的核電站痴脾,受9級(jí)特大地震影響颤介,放射性物質(zhì)發(fā)生泄漏梳星。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,329評(píng)論 3 330
  • 文/蒙蒙 一滚朵、第九天 我趴在偏房一處隱蔽的房頂上張望冤灾。 院中可真熱鬧,春花似錦辕近、人聲如沸韵吨。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,910評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽归粉。三九已至,卻和暖如春漏峰,著一層夾襖步出監(jiān)牢的瞬間糠悼,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,038評(píng)論 1 270
  • 我被黑心中介騙來泰國打工浅乔, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留倔喂,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,158評(píng)論 3 370
  • 正文 我出身青樓靖苇,卻偏偏與公主長得像席噩,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子贤壁,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,941評(píng)論 2 355

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