摘要:宗主引導(dǎo)類加載器。雙親委派模型是如何使用的我們?cè)谧远x加載器中查找是否有需要加載的文件,如果已經(jīng)加載過(guò),直接返回字節(jié)碼。
作者:畢來(lái)生1、小故事理解類加載器以及雙親委派模型
微信:878799579
首先我們來(lái)描述一個(gè)小說(shuō)場(chǎng)景,通過(guò)這個(gè)場(chǎng)景在去理解我們相關(guān)的類加載器的執(zhí)行以及雙親委派模型。
上古時(shí)代有逍遙派和萬(wàn)魔宗兩個(gè)宗派,互相對(duì)立。逍遙派比萬(wàn)魔門更加強(qiáng)勢(shì)。巔峰戰(zhàn)力更高。
有一天萬(wàn)魔宗一名長(zhǎng)老之子的仆人外出獵物期間殺掉了一小隊(duì)逍遙派歷練弟子??上帜_不干凈,留下了線索。被逍遙派探子發(fā)現(xiàn)了自己師弟師妹被殺。消息傳回宗門后。
逍遙派收到此消息后大怒,發(fā)出戰(zhàn)書。定要萬(wàn)魔門給個(gè)交代。萬(wàn)魔門宗主收到戰(zhàn)書后一臉莫名其妙,這么點(diǎn)小事也來(lái)煩我?不知道我修煉有多重要嗎?不就是殺了幾個(gè)人么?遂叫來(lái)大長(zhǎng)老,“大長(zhǎng)老你看看這戰(zhàn)書,這么點(diǎn)事情還辦不好還要我親自來(lái)處理?要你有什么用 ? 你去準(zhǔn)備點(diǎn)東西把這件事情處理一下。退下吧!”
大長(zhǎng)老灰溜溜的回去。叫來(lái)自己的兒子。上去就抽了一巴掌,看看你辦的好事。我不管了。你自己想辦法解決,解決不了就別回來(lái)了。
大長(zhǎng)老之子哭喪著臉回到了自己的府邸。從自己的寶庫(kù)挑出一些珍寶前去拜訪逍遙門,看能不能通過(guò)這些珍寶解決這件事情。結(jié)果,到了逍遙派門前,守衛(wèi)一看就這么點(diǎn)東西就想交代。對(duì)萬(wàn)魔門大長(zhǎng)老之子說(shuō):"趕緊滾關(guān)進(jìn)滾,就這么點(diǎn)東西還想給我們交代?把殺了我們師弟師妹的人帶過(guò)來(lái),不然這事兒不算完?!?/p>
大長(zhǎng)老之子那叫一個(gè)憋屈呀,寶物什么的他們也不要,看樣子他們是鐵了心想要哪些殺了他們的罪魁禍?zhǔn)?。那就把他們交出去把。他們?nèi)堑氖?。讓他們自己解決。遂派人抓捕這些人送往逍遙派,此事才得以平息。
2、小故事角色行為分析下面我們通過(guò)一張關(guān)系圖來(lái)分析一下我們的故事場(chǎng)景以及對(duì)應(yīng)我們類加載器之間的關(guān)系
通過(guò)這個(gè)圖我們可以了解到我們的小故事中與我們Java中的類加載器的對(duì)應(yīng)關(guān)系。
1、宗主:引導(dǎo)類加載器。這個(gè)類加載使用C++語(yǔ)言實(shí)現(xiàn)的,是虛擬機(jī)自身的一部分,它負(fù)責(zé)將
2、長(zhǎng)老:拓展類加載器。,它負(fù)責(zé)加載
3、長(zhǎng)老之子:系統(tǒng)類加載器。,它負(fù)責(zé)加載系統(tǒng)類路徑j(luò)ava -classpath或-D java.class.path 指定路徑下的類庫(kù),也就是我們經(jīng)常用到的classpath路徑,開(kāi)發(fā)者可以直接使用系統(tǒng)類加載器,一般情況下該類加載是程序中默認(rèn)的類加載器,通過(guò)ClassLoader類中的getSystemClassLoader()方法可以獲取到該類加載器。
4、長(zhǎng)老之子的下人:自定義類加載器。,它需要如下步驟才可以實(shí)現(xiàn)自定義效果
4.1. 繼承java.lang.ClassLoader
4.2. 重寫findClass()方法
4.3 調(diào)用defineClass()方法
雙親委派模型1、什么是雙親委派模型?
特定的類加載器在接到加載類的請(qǐng)求時(shí),首先將加載任務(wù)委托給父類加載器,依次遞歸,如果父類加載器可以完成類加載任務(wù),就成功返回;只有父類加載器無(wú)法完成此加載任務(wù)時(shí),才自己去加載。
2、雙親委派模型是如何使用的?
1)我們?cè)谧远x加載器中查找是否有需要加載的文件,如果已經(jīng)加載過(guò),直接返回字節(jié)碼。
對(duì)應(yīng)故事場(chǎng)景為:長(zhǎng)老之子的下人自己解決不了,找到長(zhǎng)老之子
2)如果自定義加載器沒(méi)有加載過(guò),則詢問(wèn)上一層加載器(即AppClassLoader)是否已經(jīng)加載過(guò)。
對(duì)應(yīng)故事場(chǎng)景為:長(zhǎng)老之子攜帶寶物前去拜訪解決此事
3) 如果沒(méi)有加載過(guò),則詢問(wèn)上一層加載器(ExtClassLoader)是否已經(jīng)加載過(guò)。
對(duì)應(yīng)故事場(chǎng)景為:大長(zhǎng)老解決此事
4) 如果沒(méi)有加載過(guò),則繼續(xù)詢問(wèn)上一層加載(BoopStrap ClassLoader)是否已經(jīng)加載過(guò)
對(duì)應(yīng)故事場(chǎng)景為:宗主解決此事
5) 如果BoopStrap ClassLoader依然沒(méi)有加載過(guò),則到自己指定類加載路徑下("sun.boot.class.path")
查看是否有對(duì)應(yīng)XXX.class字節(jié)碼,有則返回,沒(méi)有則通知下一層加載器ExtClassLoader到自己指定的
類加載路徑下(java.ext.dirs)查看
6) 最后到自定義類加載器指定的路徑還沒(méi)有找到對(duì)應(yīng)XXX.class字節(jié)碼,則拋出異常ClassNotFoundException
雙親委派有什么好處呢?1、比如兩個(gè)類A和類B都要加載Integer類:
如果不用委托而是自己加載自己的,那么類A就會(huì)加載一份Integer字節(jié)碼,然后類B又會(huì)加載一份Integer字節(jié)碼,這樣內(nèi)存中就出現(xiàn)了兩份Integer字節(jié)碼。
如果使用委托機(jī)制,會(huì)遞歸的向父類查找,也就是首選用Bootstrap嘗試加載,如果找不到再向下。這里的Integer就能在Bootstrap中找到然后加載,如果此時(shí)類B也要加載Integer,也從Bootstrap開(kāi)始,此時(shí)Bootstrap發(fā)現(xiàn)已經(jīng)加載過(guò)了Integer那么直接返回內(nèi)存中的Integer而不需要重新加載,這樣內(nèi)存中就只有一份Integer的字節(jié)碼了。
2、 安全性:
因?yàn)镃lassLoader加載的class文件來(lái)源很多,比如編譯器編譯生成的class、其他工具生成的字節(jié)碼。而有一些一些來(lái)源的class文件是不安全的,比如我們自定義一個(gè)java.lang.Integer類來(lái)覆蓋jdk中默認(rèn)的Integer類。里面寫這么一句代碼 System.exit(0);
初始化這個(gè)Integer的構(gòu)造器是會(huì)退出JVM,破壞應(yīng)用程序的正常進(jìn)行,如果使用雙親委派機(jī)制的話該Integer類永遠(yuǎn)不會(huì)被調(diào)用,以為委托BootStrapClassLoader加載后會(huì)加載JDK中的Integer類而不會(huì)加載自定義的這個(gè)
喜歡就關(guān)注我吧文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/75689.html
摘要:如果需要支持類的動(dòng)態(tài)加載或需要對(duì)編譯后的字節(jié)碼文件進(jìn)行解密操作等,就需要與類加載器打交道了。雙親委派模型,雙親委派模型,約定類加載器的加載機(jī)制。任何之類的字節(jié)碼都無(wú)法調(diào)用方法,因?yàn)樵摲椒ㄖ荒茉陬惣虞d的過(guò)程中由調(diào)用。 jvm系列 垃圾回收基礎(chǔ) JVM的編譯策略 GC的三大基礎(chǔ)算法 GC的三大高級(jí)算法 GC策略的評(píng)價(jià)指標(biāo) JVM信息查看 GC通用日志解讀 jvm的card table數(shù)據(jù)...
摘要:驗(yàn)證驗(yàn)證是連接階段的第一步,這一階段的目的是為了確保文件的字節(jié)流中包含的信息符合當(dāng)前虛擬機(jī)的要求,并且不會(huì)危害虛擬機(jī)自身的安全。字節(jié)碼驗(yàn)證通過(guò)數(shù)據(jù)流和控制流分析,確定程序語(yǔ)義是合法的符合邏輯的。 看過(guò)這篇文章,大廠面試你「雙親委派模型」,硬氣的說(shuō)一句,你怕啥? 讀該文章姿勢(shì) 打開(kāi)手頭的 IDE,按照文章內(nèi)容及思路進(jìn)行代碼跟蹤與思考 手頭沒(méi)有 IDE,先收藏,回頭看 (萬(wàn)一哪次面試問(wèn)...
摘要:類加載過(guò)程雙親委派模型聲明文章均為本人技術(shù)筆記,轉(zhuǎn)載請(qǐng)注明出處類加載過(guò)程類加載機(jī)制將類描述數(shù)據(jù)從文件中加載到內(nèi)存,并對(duì)數(shù)據(jù)進(jìn)行,解析和初始化,最終形成被直接使用的類型。深入理解虛擬機(jī)高級(jí)特性與最佳實(shí)踐加載加載階段由類加載器負(fù)責(zé),過(guò)程見(jiàn)類加載 JVM類加載過(guò)程 & 雙親委派模型 聲明 文章均為本人技術(shù)筆記,轉(zhuǎn)載請(qǐng)注明出處https://segmentfault.com/u/yzwall ...
摘要:比如我們要加載類,無(wú)論我們用哪個(gè)類加載器去加載類,這個(gè)加載請(qǐng)求最終都會(huì)委托給,這樣就保證了所有加載器加載的類都是同一個(gè)類。如果沒(méi)有雙親委派模型,那就亂了套了,完全可能搞出多個(gè)不同的類。 前言 雙親委派模型是Java加載類的機(jī)制.采用雙親委派模型的好處是Java類隨著它的類加載器一起具備了一種帶有優(yōu)先級(jí)的層級(jí)關(guān)系,通過(guò)這種層級(jí)關(guān)系可以避免類的重復(fù)加載. 1. 模型基礎(chǔ) showImg(h...
摘要:最終形成可以被虛擬機(jī)最直接使用的類型的過(guò)程就是虛擬機(jī)的類加載機(jī)制。即重寫一個(gè)類加載器的方法驗(yàn)證驗(yàn)證是連接階段的第一步,這一階段的目的是為了確保文件的字節(jié)流中包含的信息符合當(dāng)前虛擬機(jī)的要求,并且不會(huì)危害虛擬機(jī)自身的安全。 《深入理解Java虛擬機(jī):JVM高級(jí)特性與最佳實(shí)踐(第二版》讀書筆記與常見(jiàn)相關(guān)面試題總結(jié) 本節(jié)常見(jiàn)面試題(推薦帶著問(wèn)題閱讀,問(wèn)題答案在文中都有提到): 簡(jiǎn)單說(shuō)說(shuō)類加載過(guò)...
閱讀 3100·2021-10-12 10:20
閱讀 2826·2021-09-27 13:56
閱讀 802·2021-09-27 13:36
閱讀 1441·2021-09-26 09:46
閱讀 2428·2019-08-30 14:02
閱讀 2695·2019-08-28 18:14
閱讀 1274·2019-08-26 10:32
閱讀 1716·2019-08-23 18:25