真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

白話說Java虛擬機原理系列【第三章】:類加載器詳解-創(chuàng)新互聯(lián)

文章目錄
        • jvm.dll
        • BootstrapLoader:裝載系統(tǒng)類
        • ExtClassLoader:裝載擴展類
        • AppClassLoader:裝載自定義類
        • 雙親委派模型
        • 類加載器加載類的方式
        • 類加載器特性
        • 類加載器加載字節(jié)碼到JVM的過程
        • 自定義/第三方類加載器
        • `類加載器加載字節(jié)碼到哪?`
        • Class類對象
        • 破壞雙親委派機制:spi機制


公司專注于為企業(yè)提供成都網(wǎng)站設(shè)計、成都網(wǎng)站建設(shè)、微信公眾號開發(fā)、商城開發(fā),小程序設(shè)計,軟件按需網(wǎng)站設(shè)計等一站式互聯(lián)網(wǎng)企業(yè)服務(wù)。憑借多年豐富的經(jīng)驗,我們會仔細了解各客戶的需求而做出多方面的分析、設(shè)計、整合,為客戶設(shè)計出具風(fēng)格及創(chuàng)意性的商業(yè)解決方案,成都創(chuàng)新互聯(lián)更提供一系列網(wǎng)站制作和網(wǎng)站推廣的服務(wù)。

前導(dǎo)說明:
本文基于《深入理解Java虛擬機》第二版和個人理解完成,
以大白話的形式期望能用大家都看懂的描述講清楚虛擬機內(nèi)幕,
后續(xù)會增加基于《深入理解Java虛擬機》第三版內(nèi)容,并進行二個版本的對比。

JVM基本結(jié)構(gòu)圖


jvm.dll

首次要執(zhí)行JAVA程序就都需要啟動JVM虛擬機,由java.exe負責獲取JRE目錄位置中的jvm.dll動態(tài)鏈接庫,然后加載運行此庫,即JVM虛擬機。

BootstrapLoader:裝載系統(tǒng)類
  • JVM啟動初始化后,第一創(chuàng)建的類加載器為BootstrapLoader,此由C++語言實現(xiàn),加載運行后它會加載Launcher.class字節(jié)碼文件,Launcher內(nèi)部有ExtClassLoader、AppClassLoader兩個內(nèi)部類,它會先創(chuàng)建ExtClassLoader并將它的parent設(shè)置成null,然后再創(chuàng)建AppClassLoader,并將它的parent設(shè)置成ExtClassLoader。至此完成了BootstrapLoader的初始化,同時也完成了類加載器的初始化。
  • BootstrapLoader加載器負責加載JAVA安裝目錄中的類,即核心JAVA API對應(yīng)的類。如JRE目錄下的rt.jar、charsets.jar等,BootstrapLoader由C++編寫實現(xiàn),由于不是JAVA體系,所以JVM選擇了透明化該類,所以ExtClassLoader的parent設(shè)置成了null,其實代表的就是ExtClassLoader的parent為BootstrapLoader,只不過透明化了這個C++實現(xiàn)的類。
ExtClassLoader:裝載擴展類

負責加載JRE安裝目錄的"\lib\ext"目錄下的類。

AppClassLoader:裝載自定義類
  • 負責加載自己開發(fā)的類,就是環(huán)境變量中配置的"."點對應(yīng)的目錄了。其實是java.class.path對應(yīng)的目錄,即CLASSPATH目錄
  • 默認情況下使用AppClassLoader裝載應(yīng)用程序中的類。
雙親委派模型

問題:有這么寫類加載器,實際中我們要用哪個最合理呢?

這就要看一下他的運行機制:雙親委派機制

原理:就是如果有類加載的需求時,加載器先通過parent去嘗試在對應(yīng)的路徑下加載,如果parent得不到類文件,再由子加載器去加載,直到加載到文件。比如一個自定義的類,加載時,先由BootstrapLoader加載,加載不到再由ExtClassLoader加載,加載不到最后才由AppClassLoader進行加載。這就是委托模型機制,分工明確,各司其職。

原因:出于安全、保護JVM考慮,比如我自己實現(xiàn)了一個較差的String類,如果沒有此機制,那么就可以隨意加載到JVM,那可能導(dǎo)致一些問題,有了此機制,那么String永遠都是有BootstrapLoader加載,且加載的是JAVA提供的核心類庫中的類。

證明:要想證明累的加載過程是不是對,只需建一個main方法,運行一下,只不過增加一個java的啟動參數(shù):設(shè)置虛擬機參數(shù)"-XX:+TraceClassLoading"來獲取類加載信息,信息將會打印在控制臺或log。

類加載器加載類的方式
  • 隱式裝載:程序運行過程中碰到new關(guān)鍵字,則會先裝載對應(yīng)的類。
  • 顯示裝載:通過Class.forName()等類似方法顯示的調(diào)用裝載。

類加載途徑:虛擬機對類加載的規(guī)范很模糊,即最終加載成二進制流,但是二進制流從哪來沒有規(guī)定,所以可以有如下途徑獲取類的字節(jié)碼文件:

  • ①從zip包中獲取,這就是以后jar、ear、war格式的基礎(chǔ)
  • ②從網(wǎng)絡(luò)中獲取,典型應(yīng)用就是Applet
  • ③運行時計算生成,典型應(yīng)用就是動態(tài)代理技術(shù)
  • ④由其他文件生成,典型應(yīng)用就是JSP,即由JSP生成對應(yīng)的.class文件
  • ⑤從數(shù)據(jù)庫中讀取,這種場景比較少見
類加載器特性

對于任意一個類,都需要由加載它的類加載器和這個類本身一同確立其在Java虛擬機中的唯一性,每一個類加載器,都擁有一個獨立的類名稱空間。這句話表達地再簡單一點就是:比較兩個類是否"相等",只有在這兩個類是由同一個類加載器加載的前提下才有意義,否則即使這兩個類來源于同一個.class文件,被同一個虛擬機加載,只要加載它們的類加載器不同,這兩個類必定不相等。

類加載器加載字節(jié)碼到JVM的過程

在這里插入圖片描述
此處我們忽略“使用”和“卸載”兩個過程,”使用“就是我們代碼中實現(xiàn)的功能,卸載將會交由GC處理。

1.裝載:查找和導(dǎo)入class字節(jié)碼文件到運行時數(shù)據(jù)區(qū)的方法區(qū)。
2.鏈接:

檢查:檢查載入的class文件數(shù)據(jù)的正確性。
準備:給類的靜態(tài)變量分配存儲空間,存于方法區(qū)。此過程還會對(虛)方發(fā)表完成初始化。
解析:將符號引用轉(zhuǎn)成直接引用,常量池解析。

3.初始化:對靜態(tài)變量、靜態(tài)代碼塊(即靜態(tài)方法)執(zhí)行初始化工作。
最后通過加載器創(chuàng)建Class類對象存于堆,并指向方法區(qū)該類的存儲區(qū)域。

自定義/第三方類加載器

類加載器可以由第三方自己實現(xiàn)一些特殊的功能。

  • ClassLoader抽象類:類加載由此開始,會調(diào)用它的loadClass方法,查看源碼可以發(fā)現(xiàn)雙親委派的具體實現(xiàn),以及各個類加載器加載的目錄對應(yīng)的環(huán)境變量具體是哪個。
  • 自定義加載器:如果我們要保留雙親委派機制,那么需要繼承ClassLoader類并實現(xiàn)findClass方法(從源碼可知這個方法默認是空實現(xiàn),為自定義準備的擴展方法)來加載jvm默認加載器處理范圍之外的類,如果我們想更廣范圍的加載類,比如不讓AppClassLoader生效,那么只能自己重寫ClassLoader類的loadClass方法了。
類加載器加載字節(jié)碼到哪?

類加載器加載字節(jié)碼文件到運行時數(shù)據(jù)區(qū)的方法區(qū)中,然后再完成一系列字節(jié)碼文件的解析(常量池解析等),最后會創(chuàng)建一個與類文件相關(guān)的對象存入堆(即類對象)并通過指針指向方法區(qū)當前類的定義(指針指的是堆中的對象頭中會有一個引用指向方法區(qū)類字節(jié)碼定義的位置,方法區(qū)章節(jié)會詳細講解,此處知道即可)。

Class類對象
  • 類加載器加載class文件后,最終都會創(chuàng)建一個Class類的對象存于堆中,用于和方法區(qū)中的class文件內(nèi)容關(guān)聯(lián)。
  • Class類沒有public的構(gòu)造方法,Class類的對象是在裝載類時由JVM通過調(diào)用類裝載器中的defineClass()方法自動構(gòu)建的。
  • 方法區(qū)中也會保存加載當前class文件的加載器信息,因為Class類的對象是由加載器創(chuàng)建的,所以通過Class類對象可以得知用的哪個加載器。
破壞雙親委派機制:spi機制

上邊說了,雙親委派的作用就是安全,保障jdk的類只有自己的加載器能加載,但是有些時候我們需要讓我們自己提供的類被加載,該怎么辦呢?

幾種方法: 比如

  • 就是重寫源碼,這個不太可取
    就是重寫類加載器的loadClass方法,以此改變類加載的方式;
  • 通過jdk提供的spi方式,我們提供自己的實現(xiàn)類,這樣通過spi的配置,就可以成功通過雙親委派來加載到我們提供的類了。

簡單介紹SPI: spi的方法就是定義自己的實現(xiàn)類,比如數(shù)據(jù)庫驅(qū)動Driver接口的實現(xiàn)類,然后將實現(xiàn)類放到META-INF/services目錄的Driver全名的配置文件中,這樣就可以了,當然使用的時候要用ServiceLoader來加載具體的實現(xiàn)類(spi內(nèi)容可以到dubbo章節(jié)的講解中學(xué)習(xí))。

你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機房具備T級流量清洗系統(tǒng)配攻擊溯源,準確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級服務(wù)器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧


網(wǎng)頁題目:白話說Java虛擬機原理系列【第三章】:類加載器詳解-創(chuàng)新互聯(lián)
本文地址:http://weahome.cn/article/djjpie.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部