成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Java虛擬機(jī)類加載過程

lentoo / 3455人閱讀

摘要:二驗(yàn)證驗(yàn)證主要是為了確保文件的字節(jié)流中包含的信息符合當(dāng)前虛擬機(jī)的要求,并且不會(huì)危害虛擬機(jī)的自身安全。五初始化類的初始化階段是類加載過程的最后一步,該階段才真正開始執(zhí)行類中定義的程序代碼或者說是字節(jié)碼。

關(guān)注我,每天三分鐘,帶你輕松掌握一個(gè)Java相關(guān)知識(shí)點(diǎn)。

虛擬機(jī)(JVM)經(jīng)常出現(xiàn)在我們面試中,但是工作中卻很少遇到,導(dǎo)致很多同學(xué)沒有去了解過。其實(shí)除了應(yīng)付面試,作為java程序員,了解我們寫的java程序?yàn)槭裁茨苓\(yùn)行起來也是很有必要的。

我準(zhǔn)備在接下來的一系列文章中,整理虛擬機(jī)的相關(guān)運(yùn)行機(jī)制,讓同學(xué)們對(duì)虛擬機(jī)有個(gè)整體的概念。(聲明一下,文章內(nèi)容基于周志明的《深入理解Java虛擬機(jī)》,也非常推薦同學(xué)們?nèi)プx這本書)

先說一個(gè)知識(shí)點(diǎn),咱們寫的代碼,都是.java文件,但是虛擬機(jī)只認(rèn).class文件,那么誰做的這個(gè)部分的轉(zhuǎn)換呢?

看到JDK中Tools&Tool APIs了嗎,其中的javac干了這件事。

好了我們回到正題,虛擬機(jī)是怎么把class文件加載到內(nèi)存中并且執(zhí)行使用的呢?

一個(gè)class從進(jìn)入內(nèi)存到被提出內(nèi)存,總共經(jīng)歷了加載(Loading)、驗(yàn)證(Verification)、準(zhǔn)備(Preparation)、解析(Resolution)、初始化(Initialization)、使用(Using)和卸載(Unloading)這7個(gè)階段,哪這7個(gè)階段都干了啥呢?

一、加載

這個(gè)階段虛擬機(jī)主要完成了3件事:

1.通過一個(gè)類的全限定名來獲取定義此類的二進(jìn)制字節(jié)流。

2.將這個(gè)字節(jié)流所代表的靜態(tài)存儲(chǔ)結(jié)構(gòu)轉(zhuǎn)化為方法區(qū)的運(yùn)行時(shí)數(shù)據(jù)結(jié)構(gòu)。

3.在內(nèi)存中生成一個(gè)代表這個(gè)類的java.lang.Class對(duì)象,作為方法去這個(gè)類的各種數(shù)據(jù)的訪問入口。

我們可以看到,通過加載,class文件從目標(biāo)路徑轉(zhuǎn)到虛擬機(jī)的方法區(qū)中,并且clss文件中的數(shù)據(jù)能被其他人訪問了。

二、驗(yàn)證

驗(yàn)證主要是為了確保Class文件的字節(jié)流中包含的信息符合當(dāng)前虛擬機(jī)的要求,并且不會(huì)危害虛擬機(jī)的自身安全。

驗(yàn)證階段包含4個(gè)階段的檢驗(yàn)動(dòng)作:

1.文件格式檢驗(yàn),就是說傳過來的字節(jié)流一定要符合Class文件的格式規(guī)范。

2.元數(shù)據(jù)驗(yàn)證,這個(gè)是對(duì)解析出的字節(jié)碼進(jìn)行語義驗(yàn)證,以保證其信息符合Java語言規(guī)范。

3.字節(jié)碼驗(yàn)證,這個(gè)階段將對(duì)類的方法體進(jìn)行校驗(yàn)分析,保證被校驗(yàn)類方法在運(yùn)行的時(shí)候,不會(huì)危害虛擬機(jī)。

4.符號(hào)引用驗(yàn)證,這個(gè)階段校驗(yàn)發(fā)生在虛擬機(jī)將符號(hào)引用轉(zhuǎn)換為直接引用的時(shí)候,也就是在解析階段發(fā)生的。

有的同學(xué)看到這可能要疑問了,你這驗(yàn)證的4個(gè)步驟,都涉及了后面的流程,難道這些流程不是順序的嗎?

其實(shí)加載、驗(yàn)證、準(zhǔn)備、初始化和卸載這5個(gè)階段的順序是確定的,類的加載過程必須按照這個(gè)中順序開始,但是開始不代表進(jìn)行或者完成,就是這些階段被調(diào)用的順序是確定的,但是他們?cè)谑裁磿r(shí)候結(jié)束是不一定的,這些階段通常都是互相交叉混合進(jìn)行的。寶寶起名網(wǎng)

這里面解析階段的執(zhí)行順序是不確定的,這是為了支持java的運(yùn)行時(shí)綁定(多態(tài)就是動(dòng)態(tài)綁定的體現(xiàn),編譯時(shí)不知道變量指向的是父類還是子類,只有在運(yùn)行時(shí)才去找時(shí)機(jī)類型的方法表,確定方法簽名調(diào)用)。

三、準(zhǔn)備

準(zhǔn)備階段的工作是給類變量分配內(nèi)存并使之類變量初始值的階段。

這里說明一個(gè)概念:

類變量:類變量是Class級(jí)別的變量,通常用static修飾,它是在類層面共享的變量。

實(shí)例變量:實(shí)例變量是跟著對(duì)象走的,每new一個(gè)對(duì)象,就有一套類變量。

public static int value = 123;

這句在準(zhǔn)備階段,就會(huì)給變量value賦值為0,而不是123 。這就是準(zhǔn)備階段干的工作,這也是你為什么可以不給實(shí)例變量賦值初值的原因(而局部變量必須賦初值以后會(huì)解釋,這也跟虛擬機(jī)有關(guān))

四、解析

解析階段是虛擬機(jī)常量池內(nèi)的符號(hào)引用替換為直接引用的過程。

怎么理解呢?你可以把這個(gè)符號(hào)引用當(dāng)做虛擬機(jī)和class文件約定好的黑話,不管哪個(gè)虛擬機(jī)來了,都要用一套黑話他們才能交流。而他們說了什么呢,他們說了目標(biāo)對(duì)象的各種信息,這些信息在各個(gè)虛擬機(jī)里描述都不一樣,你可以把虛擬機(jī)理解為各個(gè)殺手組織,他們?cè)偈盏酵痪浜谠捗枋霭禋?duì)象的時(shí)候,在組織內(nèi)部對(duì)對(duì)象的描述都不一樣。

直接引用就是殺手組織內(nèi)部翻譯的黑話了,翻譯出來的內(nèi)容一般都包括目標(biāo)對(duì)象的指針、相對(duì)偏移量或是一個(gè)能間接定位到目標(biāo)的句柄。直接引用是與虛擬機(jī)內(nèi)存布局實(shí)現(xiàn)相關(guān)的,同一個(gè)符號(hào)引用在不同虛擬機(jī)實(shí)例上翻譯出來的直接引用一般不會(huì)相同,如果有了直接引用,那引用的目標(biāo)必定已經(jīng)在內(nèi)存中存在。

五、初始化

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

對(duì)于初始化階段,虛擬機(jī)規(guī)范有且僅有5種情況必須立即對(duì)類進(jìn)行初始化:

1.遇到new(使用new關(guān)鍵字實(shí)例化對(duì)象)、getstatic(獲取一個(gè)類的靜態(tài)字段,final修飾符修飾的靜態(tài)字段除外)、putstatic(設(shè)置一個(gè)類的靜態(tài)字段,final修飾符修飾的靜態(tài)字段除外)和invokestatic(調(diào)用一個(gè)類的靜態(tài)方法)這4條字節(jié)碼指令時(shí),如果類還沒有初始化,則必須首先對(duì)其初始化

2.使用java.lang.reflect包中的方法對(duì)類進(jìn)行反射調(diào)用時(shí),如果類還沒有初始化,則必須首先對(duì)其初始化

3.當(dāng)初始化一個(gè)類時(shí),如果其父類還沒有初始化,則必須首先初始化其父類

4.當(dāng)虛擬機(jī)啟動(dòng)時(shí),需要指定一個(gè)主類(main方法所在的類),虛擬機(jī)會(huì)首選初始化這個(gè)主類

5.當(dāng)使用JDK1.7的動(dòng)態(tài)語言支持時(shí),如果一個(gè)java.lang.invoke.MethodHandle實(shí)例最后的解析結(jié)果REF_getStatic、REF_putStatic、REF_invokeStatic的方法句柄,并且這個(gè)方法句柄所對(duì)應(yīng)的類沒有進(jìn)行過初始化,則需要先觸發(fā)其初始化。

以上就是今天的知識(shí)點(diǎn),各位小伙伴get到嗎?創(chuàng)作不易,望各位多多點(diǎn)贊收藏,有什么建議可以留言告訴我,我會(huì)積極采納!

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/75282.html

相關(guān)文章

  • 虛擬機(jī)類加載機(jī)制

    摘要:加載階段在類的加載階段,虛擬機(jī)需要完成以下件事情通過一個(gè)類的全限定名來獲取定義此類的二進(jìn)制字節(jié)流。驗(yàn)證階段驗(yàn)證是連接階段的第一步,這一階段的目的是為了確保文件的字節(jié)流中包含的信息符合當(dāng)前虛擬機(jī)的要求,并且不會(huì)危害虛擬機(jī)自身的安全。 注:本篇文章中的內(nèi)容是根據(jù)《深入理解Java虛擬機(jī)--JVM高級(jí)特性與最佳實(shí)踐》而總結(jié)的,如有理解錯(cuò)誤,歡迎大家指正! 虛擬機(jī)把描述類的數(shù)據(jù)從Class文件...

    k00baa 評(píng)論0 收藏0
  • 深入理解虛擬機(jī)之虛擬機(jī)類加載機(jī)制

    摘要:最終形成可以被虛擬機(jī)最直接使用的類型的過程就是虛擬機(jī)的類加載機(jī)制。即重寫一個(gè)類加載器的方法驗(yàn)證驗(yàn)證是連接階段的第一步,這一階段的目的是為了確保文件的字節(jié)流中包含的信息符合當(dāng)前虛擬機(jī)的要求,并且不會(huì)危害虛擬機(jī)自身的安全。 《深入理解Java虛擬機(jī):JVM高級(jí)特性與最佳實(shí)踐(第二版》讀書筆記與常見相關(guān)面試題總結(jié) 本節(jié)常見面試題(推薦帶著問題閱讀,問題答案在文中都有提到): 簡單說說類加載過...

    MadPecker 評(píng)論0 收藏0
  • JAVA 虛擬機(jī)類加載機(jī)制和字節(jié)碼執(zhí)行引擎

    摘要:實(shí)現(xiàn)這個(gè)口號(hào)的就是可以運(yùn)行在不同平臺(tái)上的虛擬機(jī)和與平臺(tái)無關(guān)的字節(jié)碼。類加載過程加載加載是類加載的第一個(gè)階段,虛擬機(jī)要完成以下三個(gè)過程通過類的全限定名獲取定義此類的二進(jìn)制字節(jié)流。驗(yàn)證目的是確保文件字節(jié)流信息符合虛擬機(jī)的要求。 引言 我們知道java代碼編譯后生成的是字節(jié)碼,那虛擬機(jī)是如何加載這些class字節(jié)碼文件的呢?加載之后又是如何進(jìn)行方法調(diào)用的呢? 一 類文件結(jié)構(gòu) 無關(guān)性基石 ja...

    RichardXG 評(píng)論0 收藏0
  • 虛擬機(jī)類加載機(jī)制

    摘要:虛擬機(jī)為了保證一個(gè)類的方法在多線程環(huán)境中被正確地加鎖同步。但啟動(dòng)類加載器不可能認(rèn)識(shí)這些代碼。實(shí)現(xiàn)模塊化熱部署的關(guān)鍵則是它的自定義類加載器機(jī)制的實(shí)現(xiàn)。 概念區(qū)分:加載、類加載、類加載器 類加載是一個(gè)過程。 加載(Loading)是類加載這一個(gè)過程的階段。 類加載器是ClassLoader類或其子類。 本文中的類的描述都包括了類和接口的可能性,因?yàn)槊總€(gè)Class文件都有可能代表J...

    airborne007 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<