摘要:加載階段虛擬機(jī)規(guī)范中并沒有進(jìn)行強(qiáng)制約束,這點(diǎn)可以交給虛擬機(jī)的具體實(shí)現(xiàn)來自由把握。由于這個類加載器是中的方法的返回值,所以一般也稱它為系統(tǒng)類加載器。如果父類加載失敗,拋出異常后,再調(diào)用自己的方法進(jìn)行加載。
類從被加載到虛擬機(jī)內(nèi)存中開始,到卸載出內(nèi)存為止,它的整個生命周期包括:加載(Loading)、驗(yàn)證(Verification)、準(zhǔn)備(Preparation)、解析(Resolution)、初始化(Initialization)、使用(Using)和卸載(Unloading)7個階段。其中驗(yàn)證、準(zhǔn)備、解析3個部分統(tǒng)稱為連接(Linking)。
加載階段:
Java虛擬機(jī)規(guī)范中并沒有進(jìn)行強(qiáng)制約束,這點(diǎn)可以交給虛擬機(jī)的具體實(shí)現(xiàn)來自由把握。
初始化時機(jī):
5種情況下必須對類進(jìn)行初始化
2.1 遇到new,getstatic,putstatic,invokestatic這4種字節(jié)碼指令時,如果類沒有進(jìn)行初始化,那就必須對類進(jìn)行初始化,比如說:new一個對象,訪問或設(shè)置static變量(final修飾的除外),調(diào)用類的靜態(tài)方法
2.2 使用java.lang.reflect包的方法對類進(jìn)行反射調(diào)用的時候,如果類沒有進(jìn)行過初始化,則需要先觸發(fā)其初始化。
2.3 當(dāng)初始化一個類時,如果其父類還沒有初始化,需要先對父類進(jìn)行初始化
2.4 當(dāng)虛擬機(jī)啟動的時候,用戶的主類(包含main方法的那個類),虛擬機(jī)會初始化這個類
2.5 當(dāng)使用JDK1.7的動態(tài)語言支持時,如果一個java.lang.invoke.MethodHandle實(shí)例最后的解析結(jié)果REF_getStatic、REF_putStatic、REF_invokeStatic的方法句柄,并且這個方法句柄所對應(yīng)的類沒有進(jìn)行過初始化,則需要先觸發(fā)其初始化。
驗(yàn)證是連接階段的第一步,這一階段的目的是為了確保Class文件的字節(jié)流中包含的信息符合當(dāng)前虛擬機(jī)的要求,并且不會危害虛擬機(jī)自身的安全。
準(zhǔn)備階段是正式為類變量分配內(nèi)存并設(shè)置類變量初始值的階段,這些變量所使用的內(nèi)存都將在方法區(qū)中進(jìn)行分配。
解析階段是虛擬機(jī)將常量池內(nèi)的符號引用替換為直接引用的過程,
符號引用(SymbolicReferences):符號引用以一組符號來描述所引用的目標(biāo),符號可以是任何形式的字面量,只要使用時能無歧義地定位到目標(biāo)即可。符號引用與虛擬機(jī)實(shí)現(xiàn)的內(nèi)存布局無關(guān),引用的目標(biāo)并不一定已經(jīng)加載到內(nèi)存中。各種虛擬機(jī)實(shí)現(xiàn)的內(nèi)存布局可以各不相同,但是它們能接受的符號引用必須都是一致的,因?yàn)榉栆玫淖置媪啃问矫鞔_定義在Java虛擬機(jī)規(guī)范的Class文件格式中。
直接引用(DirectReferences):直接引用可以是直接指向目標(biāo)的指針、相對偏移量或是一個能間接定位到目標(biāo)的句柄。直接引用是和虛擬機(jī)實(shí)現(xiàn)的內(nèi)存布局相關(guān)的,同一個符號引用在不同虛擬機(jī)實(shí)例上翻譯出來的直接引用一般不會相同。如果有了直接引用,那引用的目標(biāo)必定已經(jīng)在內(nèi)存中存在。
初始化階段是執(zhí)行類構(gòu)造器<clinit>()方法的過程。
<clinit>()方法是由編譯器自動收集類中的所有類變量的賦值動作和靜態(tài)語句塊(static{}塊)中的語句合并產(chǎn)生的,編譯器收集的順序是由語句在源文件中出現(xiàn)的順序所決定的,靜態(tài)語句塊中只能訪問到定義在靜態(tài)語句塊之前的變量,定義在它之后的變量,在前面的靜態(tài)語句塊可以賦值,但是不能訪問。
類的加載器
啟動類加載器(BootstrapClassLoader):這個類將器負(fù)責(zé)將存放在<JAVA_HOME>lib目錄中的,或者被-Xbootclasspath參數(shù)所指定的路徑中的,并且是虛擬機(jī)識別的(僅按照文件名識別,如rt.jar,名字不符合的類庫即使放在lib目錄中也不會被加載)類庫加載到虛擬機(jī)內(nèi)存中。
擴(kuò)展類加載器(ExtensionClassLoader):這個加載器由sun.misc.Launcher$ExtClassLoader實(shí)現(xiàn),它負(fù)責(zé)加載<JAVA_HOME>libext目錄中的,或者被java.ext.dirs系統(tǒng)變量所指定的路徑中的所有類庫,開發(fā)者可以直接使用擴(kuò)展類加載器。
應(yīng)用程序類加載器(ApplicationClassLoader):這個類加器由sun.misc.Launcher$App-ClassLoader實(shí)現(xiàn)。由于這個類加載器是ClassLoader中的getSystemClassLoader()方法的返回值,所以一般也稱它為系統(tǒng)類加載器。它負(fù)責(zé)加載用戶類路徑(ClassPath)上所指定的類庫,開發(fā)者可以直接使用這個類加載器,如果應(yīng)用程序中沒有自定義過自己的類加載器,一般情況下這個就是程序中默認(rèn)的類加載器。
雙親委派模型的工作過程是:如果一個類加載器收到了類加載的請求,它首先不會自己去嘗試加載這個類,而是把這個請求委派給父類加載器去完成,每一個層次的類加載器都是如此,因此所有的加載請求最終都應(yīng)該傳送到頂層的啟動類加載器中,只有當(dāng)父加載器反饋?zhàn)约簾o法完成這個加載請求(它的搜索范圍中沒有找到所需的類)時,子加載器才會嘗試自己去加載。
先檢查是否已經(jīng)被加載過,若沒有加載則調(diào)用父加載器的loadClass()方法,若父加載器為空則默認(rèn)使用啟動類加載器作為父加載器。如果父類加載失敗,拋出ClassNotFoundException異常后,再調(diào)用自己的findClass()方法進(jìn)行加載。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/69302.html
摘要:當(dāng)前類加載器和所有父類加載器都無法加載該類時,拋出異常。加載兩份相同的對象的情況和不屬于父子類加載器關(guān)系,并且各自都加載了同一個類。類加載機(jī)制與接口當(dāng)虛擬機(jī)初始化一個類時,不會初始化該類實(shí)現(xiàn)的接口。 類加載機(jī)制 概念 類加載器把class文件中的二進(jìn)制數(shù)據(jù)讀入到內(nèi)存中,存放在方法區(qū),然后在堆區(qū)創(chuàng)建一個java.lang.Class對象,用來封裝類在方法區(qū)內(nèi)的數(shù)據(jù)結(jié)構(gòu)。 1、加載: 查...
摘要:作用負(fù)責(zé)將加載到中審查每個類由誰加載父優(yōu)先的等級加載機(jī)制將字節(jié)碼重新解析成統(tǒng)一要求的對象格式類結(jié)構(gòu)分析為了更好的理解類的加載機(jī)制,我們來深入研究一下和他的方法。就算兩個是同一份字節(jié)碼,如果被兩個不同的實(shí)例所加載,也會認(rèn)為它們是兩個不同。 申明:本文首發(fā)于 詳細(xì)深入分析 ClassLoader 工作機(jī)制 ,如有轉(zhuǎn)載,注明原出處即可,謝謝配合。 什么是 ClassLoader ? 大家...
摘要:前面提到,對于數(shù)組類來說,它并沒有對應(yīng)的字節(jié)流,而是由虛擬機(jī)直接生成的。對于其他的類來說,虛擬機(jī)則需要借助類加載器來完成查找字節(jié)流的過程。驗(yàn)證階段的目的,在于確保被加載類能夠滿足虛擬機(jī)的約束條件。 Java 虛擬機(jī)將字節(jié)流轉(zhuǎn)化為 Java 類的過程。這個過程可分為加載、鏈接以及初始化 三大步驟。 加載是指查找字節(jié)流,并且據(jù)此創(chuàng)建類的過程。加載需要借助類加載器,在 Java 虛擬機(jī)中,類...
摘要:如果需要支持類的動態(tài)加載或需要對編譯后的字節(jié)碼文件進(jìn)行解密操作等,就需要與類加載器打交道了。雙親委派模型,雙親委派模型,約定類加載器的加載機(jī)制。任何之類的字節(jié)碼都無法調(diào)用方法,因?yàn)樵摲椒ㄖ荒茉陬惣虞d的過程中由調(diào)用。 jvm系列 垃圾回收基礎(chǔ) JVM的編譯策略 GC的三大基礎(chǔ)算法 GC的三大高級算法 GC策略的評價指標(biāo) JVM信息查看 GC通用日志解讀 jvm的card table數(shù)據(jù)...
反射機(jī)制與原理筆記 聲明 文章均為本人技術(shù)筆記,轉(zhuǎn)載請注明出處https://segmentfault.com/u/yzwall 反射機(jī)制 反射:當(dāng)程序無法獲知對象類型時,在運(yùn)行期間動態(tài)獲取類的所有屬性和方法,這種動態(tài)獲取類信息和動態(tài)調(diào)用對象方法的功能稱為反射機(jī)制;反射機(jī)制實(shí)現(xiàn):Class類與java.lang.reflect類庫一起實(shí)現(xiàn)機(jī)制,java.lang.reflect類庫包含F(xiàn)ield...
摘要:新生代又被劃分為三個區(qū)域和兩個幸存區(qū)。這樣劃分的目的是為了使能夠更好地管理堆內(nèi)存中的對象,包括內(nèi)存的分配及回收。新生代主要存儲新創(chuàng)建的對象和尚未進(jìn)入老年代的對象。 在Java中主要有以下三種類加載器: 引導(dǎo)類加載器(bootstrap class loader) --用來加載java的核心庫(Strin...
閱讀 3093·2021-11-24 10:47
閱讀 3847·2021-11-02 14:43
閱讀 2241·2021-09-26 10:15
閱讀 2295·2021-09-08 09:35
閱讀 580·2019-08-30 12:45
閱讀 2785·2019-08-29 17:04
閱讀 3219·2019-08-26 14:05
閱讀 1266·2019-08-26 12:10