摘要:類加載器類加載器執(zhí)行的操作就是上述加載階段做的事,通過一個類的全限定名來獲取定義這個類的二進制字節(jié)流,類加載器可以分為下列三種。應用程序類加載器,也稱為系統(tǒng)類加載器。
類加載流程:
從上面這幅圖可以看出一個類從加載到卸載有7個階段,其中驗證、準備和解析這三個步驟統(tǒng)稱為連接。類加載的過程一定會經(jīng)過加載、驗證、準備、初始化和卸載這5個過程,解析和使用則不一定。還有一點要注意的是,并不是每個步驟完全執(zhí)行完之后才會調(diào)用下一個步驟,它會在一個步驟執(zhí)行的過程中就調(diào)用下一個步驟,只是開始的時候一定會按這個順序。
一、加載
加載過程會做下面三件事。
通過一個類的全限定名來獲取定義這個類的二進制字節(jié)流。
將這個字節(jié)流的靜態(tài)存儲結(jié)構(gòu)轉(zhuǎn)化為方法區(qū)運行時的數(shù)據(jù)結(jié)構(gòu)。
在內(nèi)存中為這個類生成一個java.lang.Class對象,作為方法區(qū)這個類的訪問入口。
二、驗證
驗證是為了確保加載進來的Class文件的字節(jié)流里的內(nèi)容是符合當前虛擬機的要求,不會危害虛擬機自身的安全,比如一些非法的語句之類的,會進行下面4步驗證。
文件格式驗證,驗證字節(jié)流是否符合Class文件格式的規(guī)范,可以被當前虛擬機處理。
元數(shù)據(jù)驗證,對加載進來的類的元數(shù)據(jù)進行語義驗證,保證都符合Java語言規(guī)范。
字節(jié)碼驗證,這一步是在確保元數(shù)據(jù)符合Java語言規(guī)范后再驗證它是否有非法的,不合邏輯的地方。比如調(diào)用一個方法返回int,卻聲明一個double變量去接這個值。
符號引用驗證,就是對常量池中的各種符號引用進行驗證,看這些符號引用是否能被當前類訪問到。
三、準備
這個階段就是給類變量分配內(nèi)存并且設置初始化值,注意這里只是會分配內(nèi)存給類變量,實例變量只有在對象初始化的時候才會分配。
四、解析
在這個階段是把符號引用替換為直接引用的過程。
五、初始化
初始化是是類加載過程中的最后一步,它會根據(jù)代碼中的定義再去初始化類變量和其他的資源,到這一步就表示整個類已經(jīng)初始化完成了。
類加載器執(zhí)行的操作就是上述加載階段做的事,通過一個類的全限定名來獲取定義這個類的二進制字節(jié)流,類加載器可以分為下列三種。
啟動類加載器,它負責加載存放在
擴展類加載器,負責加載存放在
應用程序類加載器,也稱為系統(tǒng)類加載器。負責加載用戶類路徑(ClassPath)上所指定的類庫,這個加載器我們也可以直接使用。
雙親委派模型:雙親委派模式的結(jié)構(gòu)就是上圖所示,要求除了最頂層的啟動類加載器之外其他的類加載器都要有自己的父類。這里的父類不是用繼承實現(xiàn)的,是通過組合方式來復用父類類加載器。它的工作原理是當一個類加載器收到了類加載的請求,不會先自己去加載,而是先委派給父類加載器去執(zhí)行,父類加載器如果也有它的父類就繼續(xù)委派上去,直到最頂層的啟動類加載器為止。而當父類沒辦法加載的時候再一層一層往下返回,讓它的子類加載器去加載。
優(yōu)點:
這樣的好處在于讓類加載器有一種優(yōu)先級的層級關系。這里要提到一點,判斷兩個類是否相等,除了要判斷是否是同一個Class文件加載的還需要看是不是同一個類加載器加載出來的。如果不是同一個類加載器加載的,即使是同一個Class文件加載出來的類也是不相同的。舉個例子,比如java.lang.Object類,當它被加載的時候一定會被委派到最頂層的啟動類加載器去加載。所以無論你拿什么類加載器去加載,最后得到的Object類都是同一個類。如果沒有這種委派關系的話,都是Object類,但是由不一樣的類加載器加載的,各自加載出來的Object類也不相同,會造成一片混亂。
這篇文章只是大致上講了Java中類加載的過程和類加載器的設計。中間還有很多細節(jié)沒有做詳細說明。如果還想要再詳細了解的話可以去看一下《深入理解Java虛擬機:JVM高級特性與最佳實踐 第2版 》這本書,本篇文章的內(nèi)容在這本書的第七章里有詳細的解釋。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/69151.html
摘要:前面提到,對于數(shù)組類來說,它并沒有對應的字節(jié)流,而是由虛擬機直接生成的。對于其他的類來說,虛擬機則需要借助類加載器來完成查找字節(jié)流的過程。驗證階段的目的,在于確保被加載類能夠滿足虛擬機的約束條件。 Java 虛擬機將字節(jié)流轉(zhuǎn)化為 Java 類的過程。這個過程可分為加載、鏈接以及初始化 三大步驟。 加載是指查找字節(jié)流,并且據(jù)此創(chuàng)建類的過程。加載需要借助類加載器,在 Java 虛擬機中,類...
摘要:新生代又被劃分為三個區(qū)域和兩個幸存區(qū)。這樣劃分的目的是為了使能夠更好地管理堆內(nèi)存中的對象,包括內(nèi)存的分配及回收。新生代主要存儲新創(chuàng)建的對象和尚未進入老年代的對象。 在Java中主要有以下三種類加載器: 引導類加載器(bootstrap class loader) --用來加載java的核心庫(Strin...
摘要:程序計數(shù)器程序計數(shù)器是一塊較小的內(nèi)存空間,它的作用可以看做是當前線程所執(zhí)行的字節(jié)碼的行號指示器。它的主要缺點有兩個一個是效率問題,標記和清除過程的效率都不 Jvm 相關 類加載機制 本段參考 http://www.importnew.com/2374... 類加載概念 類加載指的是將類的.class文件中的二進制數(shù)據(jù)讀入到內(nèi)存中,將其放在運行時數(shù)據(jù)區(qū)的方法區(qū)內(nèi),然后在堆區(qū)創(chuàng)建一個ja...
摘要:最終形成可以被虛擬機最直接使用的類型的過程就是虛擬機的類加載機制。即重寫一個類加載器的方法驗證驗證是連接階段的第一步,這一階段的目的是為了確保文件的字節(jié)流中包含的信息符合當前虛擬機的要求,并且不會危害虛擬機自身的安全。 《深入理解Java虛擬機:JVM高級特性與最佳實踐(第二版》讀書筆記與常見相關面試題總結(jié) 本節(jié)常見面試題(推薦帶著問題閱讀,問題答案在文中都有提到): 簡單說說類加載過...
閱讀 3672·2021-09-22 15:28
閱讀 1296·2021-09-03 10:35
閱讀 878·2021-09-02 15:21
閱讀 3474·2019-08-30 15:53
閱讀 3496·2019-08-29 17:25
閱讀 569·2019-08-29 13:22
閱讀 1555·2019-08-28 18:15
閱讀 2286·2019-08-26 13:57