JVM05——JVM類加載機制知多少

我們已經(jīng)講過 JVM 相關的很多常見知識點莱革,感興趣的朋友可以在我的往期文章中查看。接下來將繼續(xù)為各位帶來 JVM 類加載機制晨炕。關注我的公眾號「Java面典」了解更多 Java 相關知識點。

類生命周期

一個 Java 類在 JVM 中的整個生命周期包括:加載(Loading)、驗證(Verification)净捅、準備(Preparation)、解析(Resolution)辩块、初始化(Initializationg)蛔六、使用(Using)和卸載(Unloading)荆永。

類生命周期.png

加載

目的

在該階段虛擬機會在內(nèi)存中生成一個代表這個類的 java.lang.Class 對象,以此作為方法區(qū)這個類的各種數(shù)據(jù)的入口国章。

加載源

類的加載可以通過以下幾個方式進行:

  1. Class 文件中獲染咴俊;
  2. 從ZIP包中讀取液兽,包括 JAR 骂删、EAR 、WAR 等格式的壓縮包四啰;
  3. 從網(wǎng)絡中獲取宁玫,如 Applet;
  4. 運行時計算生成柑晒,動態(tài)代理技術(shù)(java.lang.reflect.Porxy)欧瘪;
  5. 其他文件生成,如由 JSP 文件生成對應的 Class文件敦迄;
  6. 從數(shù)據(jù)庫中讀取恋追,如 SAP NetWeaver 這樣的中間件服務器。

驗證

目的

為了確保 Class 文件的字節(jié)流中包含的信息符合當前虛擬機的要求罚屋,并且不會危害虛擬機自身的安全苦囱。

驗證動作

驗證階段主要包含下面 4 個階段的校驗動作:

  1. 文件格式驗證。驗證字節(jié)流是否符合 Class 文件格式的規(guī)范脾猛,并且能被當前版本的虛擬機處理撕彤;
  2. 元數(shù)據(jù)驗證。對類的元數(shù)據(jù)信息進行語義校驗猛拴,保證不存在不符合 Java 語言規(guī)范的元數(shù)據(jù)信息羹铅;
  3. 字節(jié)碼驗證。對類的方法體進行校驗分析愉昆,保證被校驗類的方法在運行時不會做出危害虛擬機安全的事件职员;
  4. 符號引用驗證。發(fā)生在虛擬機符號引用轉(zhuǎn)化為直接引用的時候跛溉,對類自身以外的信息(常量池中的各種符號引用)進行匹配性校驗焊切。

準備

準備階段是正式為類變量分配內(nèi)存并設置類變量的初始值階段,即在方法區(qū)中分配這些變量所使用的內(nèi)存空間芳室。

注意

這里所說的初始值概念专肪,比如一個類變量定義為:

public static int v = 8080;

實際上變量 v 在準備階段過后的初始值為 0 而不是 8080,將 v 賦值為 8080 的 put static 指令是程序被編譯后堪侯,存放于類構(gòu)造器<client>方法之中嚎尤。
但是注意如果聲明為:

public static final int v = 8080;

在編譯階段會為 v 生成 ConstantValue 屬性,在準備階段虛擬機會根據(jù) ConstantValue 屬性將 v 賦值為 8080伍宦。

解析

解析階段是指虛擬機將常量池中的符號引用替換為直接引用的過程芽死。

符號引用

符號引用與虛擬機實現(xiàn)的布局無關乏梁,引用的目標并不一定要已經(jīng)加載到內(nèi)存中。各種虛擬機實現(xiàn)的內(nèi)存布局可以各不相同收奔,但是它們能接受的符號引用必須是一致的掌呜,因為符號引用的字面量形式明確定義在 Java 虛擬機規(guī)范的 Class 文件格式中。

直接引用

直接引用可以是指向目標的指針坪哄,相對偏移量或是一個能間接定位到目標的句柄质蕉。如果有了直接引用,那引用的目標必定已經(jīng)在內(nèi)存中存在翩肌。

解析動作

解析動作主要針對類或接口(CONSTANT_Class_info)模暗、字段(CONSTANT_Fieldref_info)、類方法(CONSTANT_Methodref_info)念祭、接口方法(CONSTANT_InterfaceMethodref_info)兑宇、方法類型(CONSTANT_MethodType_info)、方法句柄(CONSTANT_MethodHandle_info)和調(diào)用點限定符(CONSTANT_InvokeDynamic_info) 7 類符號引用進行粱坤。

初始化

類初始化是類加載過程的最后一步隶糕,此時才真正開始執(zhí)行類中定義的 Java 程序代碼(或者說是字節(jié)碼)。

類構(gòu)造器

初始化階段是執(zhí)行類構(gòu)造器<client>()方法的過程站玄。<client>()方法是由編譯器自動收集類中的類變量的賦值操作和靜態(tài)語句塊中的語句合并而成的枚驻。虛擬機會保證子<client>()方法執(zhí)行之前,父類的<client>()方法已經(jīng)執(zhí)行完畢株旷,如果一個類中沒有對靜態(tài)變量賦值也沒有靜態(tài)語句塊再登,那么編譯器可以不為這個類生成<client>()方法。

注意以下幾種情況不會執(zhí)行類初始化:

  1. 通過子類引用父類的靜態(tài)字段晾剖,只會觸發(fā)父類的初始化锉矢,而不會觸發(fā)子類的初始化;
  2. 定義對象數(shù)組齿尽,不會觸發(fā)該類的初始化沽损;
  3. 常量在編譯期間會存入調(diào)用類的常量池中,本質(zhì)上并沒有直接引用定義常量的類循头,不會觸發(fā)定義常量所在的類绵估;
  4. 通過類名獲取 Class 對象,不會觸發(fā)類的初始化贷岸;
  5. 通過 Class.forName 加載指定類時,如果指定參數(shù) initialize 為 false 時磷雇,也不會觸發(fā)類初始化偿警,其實這個參數(shù)是告訴虛擬機,是否要對類進行初始化唯笙;
  6. 通過 ClassLoader 默認的 loadClass 方法螟蒸,也不會觸發(fā)初始化動作盒使。

雙親委派

類加載器

定義

虛擬機設計團隊把加載動作放到 JVM 外部實現(xiàn),以便讓應用程序決定如何獲取所需的類七嫌,實現(xiàn)這個動作的代碼塊稱為類加載器少办。

分類

類加載器.png

JVM 提供了 3 種類加載器,啟動類加載器(Bootstrap ClassLoader)诵原、擴展類加載器(Extension ClassLoader)英妓、應用程序類加載器(Application ClassLoader)。除此之外绍赛,用戶還可實現(xiàn)自定義類加載器蔓纠。其作用及其應用范圍如下:

  • 啟動類加載器:負責加載 JAVA_HOME\lib 目錄中的,或通過-Xbootclasspath 參數(shù)指定路徑中的吗蚌,且被虛擬機認可(按文件名識別腿倚,如 rt.jar)的類;
  • 擴展類加載器:負責加載 JAVA_HOME\lib\ext 目錄中的蚯妇,或通過 java.ext.dirs 系統(tǒng)變量指定路徑中的類庫敷燎;
  • 應用程序類加載器:負責加載用戶路徑(classpath)上的類庫。

定義

類加載器之間的層次關系箩言,稱為類加載器的雙親委派模型硬贯。雙親委派模型要求除了頂層的啟動類加載器外,其余的類加載器都應該有自己的父類加載器分扎。

工作過程

雙親委派工作過程澄成,可以有簡單的一句話概括——父加載類優(yōu)先加載,其具體流程為:

  1. 當一個類收到了類加載請求畏吓;
  2. 將這個請求委派給父類去完成墨状,一一層層向上委派;
  3. 當父類加載器反饋自己無法完成這個請求的時候(在它的加載路徑下沒有找到所需加載的 Class)菲饼;
  4. 子類加載器才會嘗試自己去加載肾砂。

采用雙親委派的一個好處是比如加載位于 rt.jar 包中的類 java.lang.Object,不管是哪個加載器加載這個類宏悦,最終都是委托給頂層的啟動類加載器進行加載镐确,這樣就保證了使用不同的類加載器最終得到的都是同樣一個 Object 對象。

JVM系列推薦

JVM04——七個GC垃圾收集器饼煞,一個都不能少

JVM03——四種垃圾回收算法源葫,你都了解了哪幾種

JVM02——JVM運行時內(nèi)存

JVM01——JVM內(nèi)存區(qū)域的構(gòu)成

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市砖瞧,隨后出現(xiàn)的幾起案子息堂,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,470評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件荣堰,死亡現(xiàn)場離奇詭異床未,居然都是意外死亡,警方通過查閱死者的電腦和手機振坚,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,393評論 3 392
  • 文/潘曉璐 我一進店門薇搁,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人渡八,你說我怎么就攤上這事啃洋。” “怎么了呀狼?”我有些...
    開封第一講書人閱讀 162,577評論 0 353
  • 文/不壞的土叔 我叫張陵裂允,是天一觀的道長。 經(jīng)常有香客問我哥艇,道長绝编,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,176評論 1 292
  • 正文 為了忘掉前任貌踏,我火速辦了婚禮十饥,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘祖乳。我一直安慰自己逗堵,他們只是感情好,可當我...
    茶點故事閱讀 67,189評論 6 388
  • 文/花漫 我一把揭開白布眷昆。 她就那樣靜靜地躺著蜒秤,像睡著了一般。 火紅的嫁衣襯著肌膚如雪亚斋。 梳的紋絲不亂的頭發(fā)上作媚,一...
    開封第一講書人閱讀 51,155評論 1 299
  • 那天,我揣著相機與錄音帅刊,去河邊找鬼纸泡。 笑死,一個胖子當著我的面吹牛赖瞒,可吹牛的內(nèi)容都是我干的女揭。 我是一名探鬼主播,決...
    沈念sama閱讀 40,041評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼栏饮,長吁一口氣:“原來是場噩夢啊……” “哼吧兔!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起袍嬉,我...
    開封第一講書人閱讀 38,903評論 0 274
  • 序言:老撾萬榮一對情侶失蹤境蔼,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體欧穴,經(jīng)...
    沈念sama閱讀 45,319評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,539評論 2 332
  • 正文 我和宋清朗相戀三年泵殴,在試婚紗的時候發(fā)現(xiàn)自己被綠了涮帘。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,703評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡笑诅,死狀恐怖调缨,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情吆你,我是刑警寧澤弦叶,帶...
    沈念sama閱讀 35,417評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站妇多,受9級特大地震影響伤哺,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜者祖,卻給世界環(huán)境...
    茶點故事閱讀 41,013評論 3 325
  • 文/蒙蒙 一立莉、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧七问,春花似錦蜓耻、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,664評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至讥耗,卻和暖如春有勾,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背葛账。 一陣腳步聲響...
    開封第一講書人閱讀 32,818評論 1 269
  • 我被黑心中介騙來泰國打工柠衅, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人籍琳。 一個月前我還...
    沈念sama閱讀 47,711評論 2 368
  • 正文 我出身青樓菲宴,卻偏偏與公主長得像,于是被迫代替她去往敵國和親趋急。 傳聞我的和親對象是個殘疾皇子喝峦,可洞房花燭夜當晚...
    茶點故事閱讀 44,601評論 2 353