深入理解JVM虛擬機6:深入理解JVM類加載機制

本文轉自互聯網,侵刪

本系列文章將整理到我在GitHub上的《Java面試指南》倉庫,更多精彩內容請到我的倉庫里查看

https://github.com/h2pl/Java-Tutorial

喜歡的話麻煩點下Star哈

文章將同步到我的個人博客:

www.how2playlife.com

本文是微信公眾號【Java技術江湖】的《深入理解JVM虛擬機》其中一篇,本文部分內容來源于網絡,為了把本文主題講得清晰透徹,也整合了很多我認為不錯的技術博客內容,引用其中了一些比較好的博客文章,如有侵權,請聯系作者。

該系列博文會告訴你如何從入門到進階,一步步地學習JVM基礎知識,并上手進行JVM調優實戰,JVM是每一個Java工程師必須要學習和理解的知識點,你必須要掌握其實現原理,才能更完整地了解整個Java技術體系,形成自己的知識框架。

為了更好地總結和檢驗你的學習成果,本系列文章也會提供每個知識點對應的面試題以及參考答案。

如果對本系列文章有什么建議,或者是有什么疑問的話,也可以關注公眾號【Java技術江湖】聯系作者,歡迎你參與本系列博文的創作和修訂。

一.目標:

1.什么是類的加載?

2.類的生命周期?

3.類加載器是什么?

4.雙親委派機制是什么?

二.原理 (類的加載過程及其最終產品):

JVM將class文件字節碼文件加載到內存中, 并將這些靜態數據轉換成方法區中的運行時數據結構,在堆(并不一定在堆中,HotSpot在方法區中)中生成一個代表這個類的java.lang.Class 對象,作為方法區類數據的訪問入口。

三.過程(類的生命周期):

JVM類加載機制分為五個部分:加載,驗證,準備,解析,初始化,下面我們就分別來看一下這五個過程。其中加載、檢驗、準備、初始化和卸載這個五個階段的順序是固定的,而解析則未必。為了支持動態綁定,解析這個過程可以發生在初始化階段之后。

加載:

加載過程主要完成三件事情:

  1. 通過類的全限定名來獲取定義此類的二進制字節流
  2. 將這個類字節流代表的靜態存儲結構轉為方法區的運行時數據結構
  3. 在堆中生成一個代表此類的java.lang.Class對象,作為訪問方法區這些數據結構的入口。

這個過程主要就是類加載器完成。

校驗:

此階段主要確保Class文件的字節流中包含的信息符合當前虛擬機的要求,并且不會危害虛擬機的自身安全。

  1. 文件格式驗證:基于字節流驗證。
  2. 元數據驗證:基于方法區的存儲結構驗證。
  3. 字節碼驗證:基于方法區的存儲結構驗證。
  4. 符號引用驗證:基于方法區的存儲結構驗證。

準備:

為類變量分配內存,并將其初始化為默認值。(此時為默認值,在初始化的時候才會給變量賦值)即在方法區中分配這些變量所使用的內存空間。例如:

public static int value = 123;

此時在準備階段過后的初始值為0而不是123;將value賦值為123的putstatic指令是程序被編譯后,存放于類構造器<client>方法之中.特例:

public static final int value = 123;

此時value的值在準備階段過后就是123。

解析:

把類型中的符號引用轉換為直接引用。

  • 符號引用與虛擬機實現的布局無關,引用的目標并不一定要已經加載到內存中。各種虛擬機實現的內存布局可以各不相同,但是它們能接受的符號引用必須是一致的,因為符號引用的字面量形式明確定義在Java虛擬機規范的Class文件格式中。
  • 直接引用可以是指向目標的指針,相對偏移量或是一個能間接定位到目標的句柄。如果有了直接引用,那引用的目標必定已經在內存中存在

主要有以下四種:

  1. 類或接口的解析
  2. 字段解析
  3. 類方法解析
  4. 接口方法解析

初始化:

初始化階段是執行類構造器<client>方法的過程。<client>方法是由編譯器自動收集類中的類變量的賦值操作和靜態語句塊中的語句合并而成的。虛擬機會保證<client>方法執行之前,父類的<client>方法已經執行完畢。如果一個類中沒有對靜態變量賦值也沒有靜態語句塊,那么編譯器可以不為這個類生成<client>()方法。

java中,對于初始化階段,有且只有以下五種情況才會對要求類立刻“初始化”(加載,驗證,準備,自然需要在此之前開始):

  1. 使用new關鍵字實例化對象、訪問或者設置一個類的靜態字段(被final修飾、編譯器優化時已經放入常量池的例外)、調用類方法,都會初始化該靜態字段或者靜態方法所在的類。
  2. 初始化類的時候,如果其父類沒有被初始化過,則要先觸發其父類初始化。
  3. 使用java.lang.reflect包的方法進行反射調用的時候,如果類沒有被初始化,則要先初始化。
  4. 虛擬機啟動時,用戶會先初始化要執行的主類(含有main)
  5. jdk 1.7后,如果java.lang.invoke.MethodHandle的實例最后對應的解析結果是 REF_getStatic、REF_putStatic、REF_invokeStatic方法句柄,并且這個方法所在類沒有初始化,則先初始化。

四.類加載器:

把類加載階段的“通過一個類的全限定名來獲取描述此類的二進制字節流”這個動作交給虛擬機之外的類加載器來完成。這樣的好處在于,我們可以自行實現類加載器來加載其他格式的類,只要是二進制字節流就行,這就大大增強了加載器靈活性。系統自帶的類加載器分為三種:

  1. 啟動類加載器。
  2. 擴展類加載器。
  3. 應用程序類加載器。

五.雙親委派機制:

雙親委派機制工作過程:

如果一個類加載器收到了類加載器的請求.它首先不會自己去嘗試加載這個類.而是把這個請求委派給父加載器去完成.每個層次的類加載器都是如此.因此所有的加載請求最終都會傳送到Bootstrap類加載器(啟動類加載器)中.只有父類加載反饋自己無法加載這個請求(它的搜索范圍中沒有找到所需的類)時.子加載器才會嘗試自己去加載。

雙親委派模型的優點:java類隨著它的加載器一起具備了一種帶有優先級的層次關系.

例如類java.lang.Object,它存放在rt.jart之中.無論哪一個類加載器都要加載這個類.最終都是雙親委派模型最頂端的Bootstrap類加載器去加載.因此Object類在程序的各種類加載器環境中都是同一個類.相反.如果沒有使用雙親委派模型.由各個類加載器自行去加載的話.如果用戶編寫了一個稱為“java.lang.Object”的類.并存放在程序的ClassPath中.那系統中將會出現多個不同的Object類.java類型體系中最基礎的行為也就無法保證.應用程序也將會一片混亂.

參考文章

https://segmentfault.com/a/1190000009707894

https://www.cnblogs.com/hysum/p/7100874.html

http://c.biancheng.net/view/939.html

https://www.runoob.com/

https://blog.csdn.net/android_hl/article/details/53228348

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,461評論 6 532
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,538評論 3 417
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,423評論 0 375
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,991評論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,761評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,207評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,268評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,419評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,959評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,782評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,983評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,528評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,222評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,653評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,901評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,678評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,978評論 2 374

推薦閱讀更多精彩內容