摘要:這個(gè)階段虛擬機(jī)會(huì)保證父類的方法會(huì)在子類的方法前執(zhí)行,而且在多線程環(huán)境中,虛擬機(jī)會(huì)保證方法的同步。
一個(gè)類從加載到虛擬機(jī)到使用結(jié)束從虛擬機(jī)卸載包括了加載、驗(yàn)證、準(zhǔn)備、解析、初始化、使用、卸載,即為一個(gè)類的生命周期
下面來(lái)看一下類加載的過(guò)程,即加載、驗(yàn)證、準(zhǔn)備、解析、初始化5個(gè)階段都做了什么事:
加載階段虛擬機(jī)主要3件事:
通過(guò)類的全名獲取其二進(jìn)制字節(jié)流;
將字節(jié)流代表的靜態(tài)結(jié)構(gòu)轉(zhuǎn)化為方法區(qū)識(shí)別的運(yùn)行時(shí)數(shù)據(jù)結(jié)構(gòu);
在內(nèi)存中實(shí)例化這個(gè)類的java.lang.Class對(duì)象(不一定在堆內(nèi)存中的,HotSpot就將Class對(duì)象放在了方法區(qū)里),程序訪問(wèn)這個(gè)類在方法區(qū)中的類型數(shù)據(jù)時(shí)會(huì)通過(guò)這個(gè)類去訪問(wèn);
以上三點(diǎn)虛擬機(jī)并不要求如何實(shí)現(xiàn),只是一個(gè)規(guī)范,比如第一步,通過(guò)類全名獲取其二進(jìn)制流,動(dòng)態(tài)代理技術(shù)是在運(yùn)行時(shí)獲取、JSP應(yīng)用是根據(jù)jsp文件獲取并生成對(duì)應(yīng)的Class以及從ZIP包中獲?。↗AR、EAR、WA同理)等
驗(yàn)證階段大體上會(huì)完成4個(gè)階段的驗(yàn)證(文件格式驗(yàn)證、元數(shù)據(jù)驗(yàn)證、字節(jié)碼驗(yàn)證、符號(hào)引用驗(yàn)證),以保證虛擬機(jī)中類的規(guī)范和安全。
文件格式驗(yàn)證,校驗(yàn)字節(jié)流是否復(fù)合Class文件的格式:
驗(yàn)證文件是否以魔數(shù)0xCAFEBABE(十六進(jìn)制class文件中的前4個(gè)字節(jié))開頭;
主、次版本號(hào)(十六進(jìn)制class文件中的第5、第6個(gè)字節(jié))能否被當(dāng)前版本的虛擬機(jī)處理;
常量池中是否有不被支持的類型;
指向常量的索引中是否指向了不存在的常量;
Class文件中各個(gè)部分以及文件本身是否有被刪除或附加的其他信息;
......
元數(shù)據(jù)類型,校驗(yàn)語(yǔ)義是否符合Java語(yǔ)言規(guī)范的要求:
驗(yàn)證類是否有父類(除了java.lang.Object);
驗(yàn)證父類是否繼承了不可被繼承的類;
如果不是抽象類,那么要判斷是否實(shí)現(xiàn)了父類或接口的所要求實(shí)現(xiàn)的所有方法;
......
字節(jié)碼驗(yàn)證,校驗(yàn)類的方法體,確定語(yǔ)義是否符合邏輯:
保證操作數(shù)棧中的數(shù)據(jù)類型與指令序列一致;
保證跳轉(zhuǎn)指令不會(huì)跳到方法體外的字節(jié)碼指令上;
保證方法體中的類型轉(zhuǎn)換有效;
......
階段3:準(zhǔn)備準(zhǔn)備階段是為類變量分配內(nèi)存并設(shè)置類變量初始值的階段
這里所說(shuō)的初始值并不是指代碼賦的值,而是數(shù)據(jù)類型的默認(rèn)值,如public static int value = 123; 在準(zhǔn)備階段過(guò)后,value會(huì)被置為0,而不是123。
同時(shí)要注意,public static final int value = 123; 這種使用final修飾的變量,在準(zhǔn)備階段就會(huì)被賦值為123,而不是初始值。
解析階段會(huì)將常量池內(nèi)的符號(hào)引用轉(zhuǎn)換為直接引用,關(guān)于符號(hào)引用和直接引用的解釋如下:
符號(hào)引用:以一組符號(hào)來(lái)描述所引用的目,比如定義了在類IntF中定義了intValue = 123,接著讓Test.foo中的a變量指向Intf.intValue:
public class Test{ public void foo(){ int a = Intf.intValue; } } class Intf{ public static int intValue = 123; }
編譯代碼之后我們用javap -verbose Test來(lái)查看class文件中的內(nèi)容:
Constant pool: #1 = Methodref #4.#12 // java/lang/Object."":()V #2 = Fieldref #13.#14 // Intf.intValue:I #3 = Class #15 // Test #4 = Class #16 // java/lang/Object // 省略部分代碼... public void foo(); descriptor: ()V flags: ACC_PUBLIC Code: stack=1, locals=2, args_size=1 0: getstatic #2 // Field Intf.intValue:I 3: istore_1 4: return LineNumberTable: line 3: 0 line 4:
可以看到常量池第2項(xiàng)是一個(gè)符號(hào)引用,指向了Intf.intValue
直接引用:就是我們常說(shuō)的指針或者句柄,直接引用的目標(biāo)一定會(huì)在虛擬機(jī)內(nèi)存中存在。
階段5:初始化初始化階段是類加載的最后一個(gè)階段,主要執(zhí)行類的
這個(gè)階段虛擬機(jī)會(huì)保證父類的
參考文獻(xiàn):《深入理解Java虛擬機(jī)》 - 周志明
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/72915.html
摘要:類加載過(guò)程雙親委派模型聲明文章均為本人技術(shù)筆記,轉(zhuǎn)載請(qǐng)注明出處類加載過(guò)程類加載機(jī)制將類描述數(shù)據(jù)從文件中加載到內(nèi)存,并對(duì)數(shù)據(jù)進(jìn)行,解析和初始化,最終形成被直接使用的類型。深入理解虛擬機(jī)高級(jí)特性與最佳實(shí)踐加載加載階段由類加載器負(fù)責(zé),過(guò)程見(jiàn)類加載 JVM類加載過(guò)程 & 雙親委派模型 聲明 文章均為本人技術(shù)筆記,轉(zhuǎn)載請(qǐng)注明出處https://segmentfault.com/u/yzwall ...
任何程序都需要加載到內(nèi)存才能與CPU進(jìn)行交流 同理, 字節(jié)碼.class文件同樣需要加載到內(nèi)存中,才可以實(shí)例化類 ClassLoader的使命就是提前加載.class 類文件到內(nèi)存中 在加載類時(shí),使用的是Parents Delegation Model(溯源委派加載模型) Java的類加載器是一個(gè)運(yùn)行時(shí)核心基礎(chǔ)設(shè)施模塊,主要是在啟動(dòng)之初進(jìn)行類的加載、鏈接、初始化 showImg(https://s...
摘要:學(xué)習(xí)能更深入的理解這門語(yǔ)言,能理解語(yǔ)言底層的執(zhí)行過(guò)程,深入到字節(jié)碼層次。 目錄 ? 前言 程序的運(yùn)行 1.JVM類加載機(jī)制 ①一般在什么情況下會(huì)去加載一個(gè)類?也就是說(shuō),什么時(shí)候.class字節(jié)碼文件中加載這個(gè)類到JVM內(nèi)存里來(lái)? ②驗(yàn)證、準(zhǔn)備、初始化 ③初始化 2.類加載器和雙親委派機(jī)制 ...
摘要:執(zhí)行引擎作用執(zhí)行字節(jié)碼,或者執(zhí)行本地方法運(yùn)行時(shí)數(shù)據(jù)區(qū)其實(shí)就是指在運(yùn)行期間,其對(duì)內(nèi)存空間的劃分和分配。 雖是讀書筆記,但是如轉(zhuǎn)載請(qǐng)注明出處https://uestc-dpz.github.io..拒絕伸手復(fù)制黨 JVM Java 虛擬機(jī) Java 虛擬機(jī)(Java virtual machine,JVM)是運(yùn)行 Java 程序必不可少的機(jī)制。JVM實(shí)現(xiàn)了Java語(yǔ)言最重要的特征:即平臺(tái)...
摘要:類加載過(guò)程共分為加載驗(yàn)證準(zhǔn)備解析初始化使用和卸載七個(gè)階段這些階段通常都是互相交叉的混合式進(jìn)行的,通常會(huì)在一個(gè)階段執(zhí)行的過(guò)程中調(diào)用或激活另外一個(gè)階段。 JVM類加載過(guò)程共分為加載、驗(yàn)證、準(zhǔn)備、解析、初始化、使用和卸載七個(gè)階段showImg(https://segmentfault.com/img/bV0D9R?w=634&h=203);這些階段通常都是互相交叉的混合式進(jìn)行的,通常會(huì)在一個(gè)...
摘要:而字節(jié)碼運(yùn)行在之上,所以不用關(guān)心字節(jié)碼是在哪個(gè)操作系統(tǒng)編譯的,只要符合規(guī)范,那么,這個(gè)字節(jié)碼文件就是可運(yùn)行的。好處防止內(nèi)存中出現(xiàn)多份同樣的字節(jié)碼安全性角度特別說(shuō)明類加載器在成功加載某個(gè)類之后,會(huì)把得到的類的實(shí)例緩存起來(lái)。 前言 只有光頭才能變強(qiáng) JVM在準(zhǔn)備面試的時(shí)候就有看了,一直沒(méi)時(shí)間寫筆記。現(xiàn)在到了一家公司實(shí)習(xí),閑的時(shí)候就寫寫,刷刷JVM博客,刷刷電子書。 學(xué)習(xí)JVM的目的也很簡(jiǎn)單...
閱讀 3801·2021-11-17 09:33
閱讀 2020·2021-10-26 09:51
閱讀 1535·2021-09-29 09:44
閱讀 1686·2019-08-30 15:55
閱讀 1454·2019-08-30 15:52
閱讀 2331·2019-08-30 15:43
閱讀 3440·2019-08-29 17:00
閱讀 2307·2019-08-29 16:23