国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

《深入理解Java虛擬機》讀書筆記: 類加載器

這篇具有很好參考價值的文章主要介紹了《深入理解Java虛擬機》讀書筆記: 類加載器。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

《深入理解Java虛擬機》讀書筆記: 類加載器

????????? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?類加載器

?

??虛擬機設(shè)計團隊把類加載階段中的“通過一個類的全限定名來獲取描述此類的二進制字節(jié)流”這個動作放到Java虛擬機外部去實現(xiàn),以便讓應(yīng)用程序自己決定如何去獲取所需要的類。實現(xiàn)這個動作的代碼模塊稱為“類加載器”。

類加載器可以說是Java語言的一項創(chuàng)新,也是Java語言流行的重要原因之一,它最初是為了滿足Java Applet的需求而開發(fā)出來的。雖然目前Java Applet技術(shù)基本上已經(jīng)“死掉”,但類加載器卻在類層次劃分、OSGi、熱部署、代碼加密等領(lǐng)域大放異彩,成為了Java技術(shù)體系中一塊重要的基石,可謂是失之桑榆,收之東隅。

?

1 、類與類加載器

??類加載器雖然只用于實現(xiàn)類的加載動作,但它在Java程序中起到的作用卻遠遠不限于類加載階段。對于任意一個類,都需要由加載它的類加載器和這個類本身一同確立其在Java虛擬機中的唯一性,每一個類加載器,都擁有一個獨立的類名稱空間。這句話可以表達得更通俗一些:比較兩個類是否“相等”,只有在這兩個類是由同一個類加載器加載的前提下才有意義,否則,即使這兩個類來源于同一個Class文件,被同一個虛擬機加載,只要加載它們的類加載器不同,那這兩個類就必定不相等。

??這里所指的“相等”,包括代表類的Class對象的equals()方法、isAssignableFrom()方法、isInstance()方法的返回結(jié)果,也包括使用instanceof關(guān)鍵字做對象所屬關(guān)系判定等情況。

?

2 、雙親委派模型

??從Java虛擬機的角度來講,只存在兩種不同的類加載器:一種是啟動類加載器(Bootstrap ClassLoader),這個類加載器使用C++語言實現(xiàn),是虛擬機自身的一部分;另一種就是所有其他的類加載器,這些類加載器都由Java語言實現(xiàn),獨立于虛擬機外部,并且全都繼承自抽象類java.lang.ClassLoader。

從Java開發(fā)人員的角度來看,類加載器還可以劃分得更細致一些,絕大部分Java程序都會使用到以下3種系統(tǒng)提供的類加載器。

?

(1)啟動類加載器(Bootstrap ClassLoader)

??前面已經(jīng)介紹過,這個類將器負(fù)責(zé)將存放在<JAVA_HOME>\lib目錄中的,或者被-Xbootclasspath參數(shù)所指定的路徑中的,并且是虛擬機識別的(僅按照文件名識別,如rt.jar,名字不符合的類庫即使放在lib目錄中也不會被加載)類庫加載到虛擬機內(nèi)存中。啟動類加載器無法被Java程序直接引用,用戶在編寫自定義類加載器時,如果需要把加載請求委派給引導(dǎo)類加載器,那直接使用null代替即可。

?

(2)擴展類加載器(Extension ClassLoader)

??這個加載器由sun.misc.Launcher$ExtClassLoader實現(xiàn),它負(fù)責(zé)加載<JAVA_HOME>\lib\ext目錄中的,或者被java.ext.dirs系統(tǒng)變量所指定的路徑中的所有類庫,開發(fā)者可以直接使用擴展類加載器。

?

(3)應(yīng)用程序類加載器(Application ClassLoader)

??這個類加載器由sun.misc.Launcher$App-ClassLoader實現(xiàn)。由于這個類加載器是ClassLoader中的getSystemClassLoader()方法的返回值,所以一般也稱它為系統(tǒng)類加載器。它負(fù)責(zé)加載用戶類路徑(ClassPath)上所指定的類庫,開發(fā)者可以直接使用這個類加載器,如果應(yīng)用程序中沒有自定義過自己的類加載器,一般情況下這個就是程序中默認(rèn)的類加載器。

?

??我們的應(yīng)用程序都是由這3種類加載器互相配合進行加載的,如果有必要,還可以加入自己定義的類加載器。這些類加載器之間的關(guān)系一般如下圖所示。

?

《深入理解Java虛擬機》讀書筆記: 類加載器

????????????? ? ? ? ? ? ? ? ? ? 類加載器雙親委派模型

?

??雙親委派模型的工作過程是:如果一個類加載器收到了類加載的請求,它首先不會自己去嘗試加載這個類,而是把這個請求委派給父類加載器去完成,每一個層次的類加載器都是如此,因此所有的加載請求最終都應(yīng)該傳送到頂層的啟動類加載器中,只有當(dāng)父加載器反饋自己無法完成這個加載請求(它的搜索范圍中沒有找到所需的類)時,子加載器才會嘗試自己去加載。

?

3 、破壞雙親委派模型

??上文提到過雙親委派模型并不是一個強制性的約束模型,而是Java設(shè)計者推薦給開發(fā)者的類加載器實現(xiàn)方式。在Java的世界中大部分的類加載器都遵循這個模型,但也有例外,到目前為止,雙親委派模型主要出現(xiàn)過3較大規(guī)模的“被破壞”情況。

第一次“被破壞”

??雙親委派模型的第一次“被破壞”其實發(fā)生在雙親委派模型出現(xiàn)之前——即JDK 1.2發(fā)布之前。由于雙親委派模型在JDK 1.2之后才被引入,而類加載器和抽象類java.lang. ClassLoader則在JDK 1.0時代就已經(jīng)存在,面對已經(jīng)存在的用戶自定義類加載器的實現(xiàn)代碼,Java設(shè)計者引入雙親委派模型時不得不做出一些妥協(xié)。為了向前兼容,JDK 1.2之后的java.lang.ClassLoader添加了一個新的protected方法findClass(),在此之前,用戶去繼承java. lang.ClassLoader的唯一目的就是為了重寫loadClass()方法,因為虛擬機在進行類加載的時候會調(diào)用加載器的私有方法loadClassInternal(),而這個方法的唯一邏輯就是去調(diào)用自己的loadClass()。

上一節(jié)我們已經(jīng)看過loadClass()方法的代碼,雙親委派的具體邏輯就實現(xiàn)在這個方法之中,JDK 1.2之后已不提倡用戶再去覆蓋loadClass()方法,而應(yīng)當(dāng)把自己的類加載邏輯寫到findClass()方法中,在loadClass()方法的邏輯里如果父類加載失敗,則會調(diào)用自己的findClass()方法來完成加載,這樣就可以保證新寫出來的類加載器是符合雙親委派規(guī)則的。

?

第二次“被破壞”

??雙親委派模型的第二次“被破壞”是由這個模型自身的缺陷所導(dǎo)致的,雙親委派很好地解決了各個類加載器的基礎(chǔ)類的統(tǒng)一問題(越基礎(chǔ)的類由越上層的加載器進行加載),基礎(chǔ)類之所以稱為“基礎(chǔ)”,是因為它們總是作為被用戶代碼調(diào)用的API,但世事往往沒有絕對的完美,如果基礎(chǔ)類又要調(diào)用回用戶的代碼,那該怎么辦?

這并非是不可能的事情,一個典型的例子便是JNDI服務(wù),JNDI現(xiàn)在已經(jīng)是Java的標(biāo)準(zhǔn)服務(wù),它的代碼由啟動類加載器去加載(在JDK 1.3時放進去的rt.jar),但JNDI的目的就是對資源進行集中管理和查找,它需要調(diào)用由獨立廠商實現(xiàn)并部署在應(yīng)用程序的ClassPath下的JNDI接口提供者(SPI,Service Provider Interface)的代碼,但啟動類加載器不可能“認(rèn)識”這些代碼?。∧窃撛趺崔k?

??為了解決這個問題,Java設(shè)計團隊只好引入了一個不太優(yōu)雅的設(shè)計:線程上下文類加載器(Thread Context ClassLoader)。這個類加載器可以通過java.lang.Thread類的setContextClassLoaser()方法進行設(shè)置,如果創(chuàng)建線程時還未設(shè)置,它將會從父線程中繼承一個,如果在應(yīng)用程序的全局范圍內(nèi)都沒有設(shè)置過的話,那這個類加載器默認(rèn)就是應(yīng)用程序類加載器。

??有了線程上下文類加載器,就可以做一些“舞弊”的事情了,JNDI服務(wù)使用這個線程上下文類加載器去加載所需要的SPI代碼,也就是父類加載器請求子類加載器去完成類加載的動作,這種行為實際上就是打通了雙親委派模型的層次結(jié)構(gòu)來逆向使用類加載器,實際上已經(jīng)違背了雙親委派模型的一般性原則,但這也是無可奈何的事情。Java中所有涉及SPI的加載動作基本上都采用這種方式,例如JNDI、JDBC、JCE、JAXB和JBI等。

?

第三次“被破壞”

??雙親委派模型的第三次“被破壞”是由于用戶對程序動態(tài)性的追求而導(dǎo)致的,這里所說的“動態(tài)性”指的是當(dāng)前一些非?!盁衢T”的名詞:代碼熱替換(HotSwap)、模塊熱部署(Hot Deployment)等,說白了就是希望應(yīng)用程序能像我們的計算機外設(shè)那樣,接上鼠標(biāo)、U盤,不用重啟機器就能立即使用,鼠標(biāo)有問題或要升級就換個鼠標(biāo),不用停機也不用重啟。對于個人計算機來說,重啟一次其實沒有什么大不了的,但對于一些生產(chǎn)系統(tǒng)來說,關(guān)機重啟一次可能就要被列為生產(chǎn)事故,這種情況下熱部署就對軟件開發(fā)者,尤其是企業(yè)級軟件開發(fā)者具有很大的吸引力。

?

??Sun公司所提出的JSR-294、JSR-277[插圖]規(guī)范在與JCP組織的模塊化規(guī)范之爭中落敗給JSR-291(即OSGi R4.2),雖然Sun不甘失去Java模塊化的主導(dǎo)權(quán),獨立在發(fā)展Jigsaw項目,但目前OSGi已經(jīng)成為了業(yè)界“事實上”的Java模塊化標(biāo)準(zhǔn),而OSGi實現(xiàn)模塊化熱部署的關(guān)鍵則是它自定義的類加載器機制的實現(xiàn)。每一個程序模塊(OSGi中稱為Bundle)都有一個自己的類加載器,當(dāng)需要更換一個Bundle時,就把Bundle連同類加載器一起換掉以實現(xiàn)代碼的熱替換。

在OSGi環(huán)境下,類加載器不再是雙親委派模型中的樹狀結(jié)構(gòu),而是進一步發(fā)展為更加復(fù)雜的網(wǎng)狀結(jié)構(gòu),當(dāng)收到類加載請求時,OSGi將按照下面的順序進行類搜索:

(1)將以java.*開頭的類委派給父類加載器加載。

(2)否則,將委派列表名單內(nèi)的類委派給父類加載器加載。

(3)否則,將Import列表中的類委派給Export這個類的Bundle的類加載器加載。

(4)否則,查找當(dāng)前Bundle的ClassPath,使用自己的類加載器加載。

(5)否則,查找類是否在自己的Fragment Bundle中,如果在,則委派給Fragment Bundle的類加載器加載。

(6)否則,查找Dynamic Import列表的Bundle,委派給對應(yīng)Bundle的類加載器加載。

(7)否則,類查找失敗。文章來源地址http://www.zghlxwxcb.cn/news/detail-664816.html

?

到了這里,關(guān)于《深入理解Java虛擬機》讀書筆記: 類加載器的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 《深入理解Java虛擬機》讀書筆記:垃圾收集算法

    《深入理解Java虛擬機》讀書筆記:垃圾收集算法

    由于垃圾收集算法的實現(xiàn)涉及大量的程序細節(jié),而且各個平臺的虛擬機操作內(nèi)存的方法又各不相同,因此本節(jié)不打算過多地討論算法的實現(xiàn),只是介紹幾種算法的思想及其發(fā)展過程。 垃圾收集算法概要 ? 標(biāo)記-清除算法最基礎(chǔ)的收集算法是“標(biāo)記-清除”(Mark-Sweep)算法,算

    2024年02月13日
    瀏覽(19)
  • 《深入理解Java虛擬機》讀書筆記:HotSpot虛擬機對象探秘

    《深入理解Java虛擬機》讀書筆記:HotSpot虛擬機對象探秘

    基于實用優(yōu)先的原則,以常用的虛擬機HotSpot和常用的內(nèi)存區(qū)域Java堆為例,深入探討HotSpot虛擬機在Java堆中對象分配、布局和訪問的全過程。以下是本節(jié)內(nèi)容的腦圖。 ? HotSpot虛擬機對象探秘腦圖 ? 創(chuàng)建對象大致分為5步:1.檢查類是否加載,沒有加載先加載類 2.分配內(nèi)存 3.初始

    2024年02月14日
    瀏覽(19)
  • 《深入理解Java虛擬機》讀書筆記:字節(jié)碼指令簡介

    《深入理解Java虛擬機》讀書筆記:字節(jié)碼指令簡介

    字節(jié)碼指令簡介 ? Java虛擬機的指令由一個字節(jié)長度的、代表著某種特定操作含義的數(shù)字(稱為操作碼,Opcode)以及跟隨其后的零至多個代表此操作所需參數(shù)(稱為操作數(shù),Operands)而構(gòu)成。由于Java虛擬機采用面向操作數(shù)棧而不是寄存器的架構(gòu)(這兩種架構(gòu)的區(qū)別和影響將在

    2024年02月12日
    瀏覽(20)
  • 《深入理解Java虛擬機》讀書筆記:垃圾收集器

    《深入理解Java虛擬機》讀書筆記:垃圾收集器

    垃圾收集器 ? HotSpot虛擬機包含的所有收集器如圖3-5所示。圖3-5展示了7種作用于不同分代的收集器,如果兩個收集器之間存在連線,就說明它們可以搭配使用。 新生代收集器:Serial、ParNew、Parallel Scavenge,新生代收集器均采用復(fù)制算法 老年代收集器:Serial Old(標(biāo)記-整理算法

    2024年02月13日
    瀏覽(23)
  • 《深入理解Java虛擬機》讀書筆記:判斷對象是否存活

    《深入理解Java虛擬機》讀書筆記:判斷對象是否存活

    本節(jié)內(nèi)容的概要如下; 對象已死嗎? ? 給對象中添加一個引用計數(shù)器,每當(dāng)有一個地方引用它時,計數(shù)器值就加1;當(dāng)引用失效時,計數(shù)器值就減1;任何時刻計數(shù)器為0的對象就是不可能再被使用的。 客觀地說,引用計數(shù)算法(Reference Counting)的實現(xiàn)簡單,判定效率也很高,在

    2024年02月14日
    瀏覽(146)
  • 《深入理解Java虛擬機》讀書筆記:內(nèi)存分配與回收策略

    《深入理解Java虛擬機》讀書筆記:內(nèi)存分配與回收策略

    Java技術(shù)體系中所提倡的自動內(nèi)存管理最終可以歸結(jié)為自動化地解決了兩個問題:給對象分配內(nèi)存以及回收分配給對象的內(nèi)存。關(guān)于回收內(nèi)存這一點,我們已經(jīng)使用了大量篇幅去介紹虛擬機中的垃圾收集器體系以及運作原理,現(xiàn)在我們再一起來探討一下給對象分配內(nèi)存的那點事

    2024年02月13日
    瀏覽(27)
  • 《深入理解Java虛擬機》讀書筆記:HotSpot的算法實現(xiàn)

    《深入理解Java虛擬機》讀書筆記:HotSpot的算法實現(xiàn)

    HotSpot的算法實現(xiàn)概要 由于目前的主流Java虛擬機使用的都是準(zhǔn)確式GC(這個概念在第1章介紹Exact VM對Classic VM的改進時講過),所以當(dāng)執(zhí)行系統(tǒng)停頓下來后,并不需要一個不漏地檢查完所有執(zhí)行上下文和全局的引用位置,虛擬機應(yīng)當(dāng)是有辦法直接得知哪些地方存放著對象引用。

    2024年02月13日
    瀏覽(17)
  • 《深入理解Java虛擬機》讀書筆記:Class類文件的結(jié)構(gòu)

    《深入理解Java虛擬機》讀書筆記:Class類文件的結(jié)構(gòu)

    Class類文件的結(jié)構(gòu) ? Sun公司以及其他虛擬機提供商發(fā)布了許多可以運行在各種不同平臺上的虛擬機,這些虛擬機都可以載入和執(zhí)行同一種平臺無關(guān)的的程序存儲格式——字節(jié)碼(ByteCode),從而實現(xiàn)了程序的“一次編寫,到處運行”。 ? Java虛擬機提供的語言無關(guān)性 ? “Clas

    2024年02月13日
    瀏覽(19)
  • 《深入理解Java虛擬機》讀書筆記:基于棧的字節(jié)碼解釋執(zhí)行引擎

    《深入理解Java虛擬機》讀書筆記:基于棧的字節(jié)碼解釋執(zhí)行引擎

    ??虛擬機是如何調(diào)用方法的內(nèi)容已經(jīng)講解完畢,從本節(jié)開始,我們來探討虛擬機是如何執(zhí)行方法中的字節(jié)碼指令的。上文中提到過,許多Java虛擬機的執(zhí)行引擎在執(zhí)行Java代碼的時候都有 解釋執(zhí)行(通過解釋器執(zhí)行) 和 編譯執(zhí)行(通過即時編譯器產(chǎn)生本地代碼執(zhí)行) 兩種選

    2024年02月11日
    瀏覽(51)
  • 《深入理解Java虛擬機(第三版)》讀書筆記:Java內(nèi)存區(qū)域與內(nèi)存溢出異常、垃圾收集器與內(nèi)存分配策略

    《深入理解Java虛擬機(第三版)》讀書筆記:Java內(nèi)存區(qū)域與內(nèi)存溢出異常、垃圾收集器與內(nèi)存分配策略

    下文是閱讀《深入理解Java虛擬機(第3版)》這本書的讀書筆記,如有侵權(quán),請聯(lián)系刪除。 Java虛擬機在執(zhí)行Java程序的過程中會把它所管理的內(nèi)存劃分為若干個不同的數(shù)據(jù)區(qū)域。這些區(qū)域有各自的用途,以及創(chuàng)建和銷毀的時間,有的區(qū)域隨著虛擬機進程的啟動而一直存在,有

    2024年02月03日
    瀏覽(24)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包