從匯編碼分析java對(duì)象的創(chuàng)建過(guò)程(推薦)
源碼:
class T {
int m = 8;
}
T t = new T();
匯編碼:
0 new #2 <T> 3 dup 4 invokespecial #3 <T.<init>> 7 astore_1 8 return
new #2
申請(qǐng)內(nèi)存,在堆里面創(chuàng)建一個(gè)新對(duì)象。
半初始化,新建對(duì)象中的m值是0。
dup
復(fù)制操作,因?yàn)閕nvokespecial會(huì)消耗一份引用,所以先復(fù)制一份
invokespecial
4 invokespecial #3 <T.>
init是調(diào)用它的構(gòu)造方法。
此時(shí)對(duì)象中的m值是8。
astore_1
將符號(hào)和對(duì)象建立關(guān)聯(lián),即t和堆中的對(duì)象。
其實(shí)很簡(jiǎn)單,今天看一個(gè)視頻說(shuō)了半天。。。
知識(shí)點(diǎn)補(bǔ)充:java對(duì)象的創(chuàng)建過(guò)程
大家都知道,java使用new 關(guān)鍵字進(jìn)行對(duì)象的創(chuàng)建,但這只是從語(yǔ)言層次上理解了對(duì)象的創(chuàng)建,下邊我們從jvm的角度來(lái)看看,對(duì)象是怎么被創(chuàng)建出來(lái)的,即對(duì)象的創(chuàng)建過(guò)程。
對(duì)象的創(chuàng)建大概分為以下幾步:
1:檢查類(lèi)是否已經(jīng)被加載;
2:為對(duì)象分配內(nèi)存空間;
3:為對(duì)象字段設(shè)置零值;
4:設(shè)置對(duì)象頭;
5:執(zhí)行構(gòu)造方法。
第一步,當(dāng)程序遇到new 關(guān)鍵字時(shí),首先會(huì)去運(yùn)行時(shí)常量池中查找該引用所指向的類(lèi)有沒(méi)有被虛擬機(jī)加載,如果沒(méi)有被加載,那么會(huì)進(jìn)行類(lèi)的加載過(guò)程,如果已經(jīng)被加載,那么進(jìn)行下一步,為對(duì)象分配內(nèi)存空間;
第二步,加載完類(lèi)之后,需要在堆內(nèi)存中為該對(duì)象分配一定的空間,該空間的大小在類(lèi)加載完成時(shí)就已經(jīng)確定下來(lái)了,這里多說(shuō)一點(diǎn),為對(duì)象分配內(nèi)存空間有兩種方式:
(1)第一種是jvm將堆區(qū)抽象為兩塊區(qū)域,一塊是已經(jīng)被其他對(duì)象占用的區(qū)域,另一塊是空白區(qū)域,中間通過(guò)一個(gè)指針進(jìn)行標(biāo)注,這時(shí)只需要將指針向空白區(qū)域移動(dòng)相應(yīng)大小空間,就完成了內(nèi)存的分配,當(dāng)然這種劃分的方式要求虛擬機(jī)的對(duì)內(nèi)存是地址連續(xù)的,且虛擬機(jī)帶有內(nèi)存壓縮機(jī)制,可以在內(nèi)存分配完成時(shí)壓縮內(nèi)存,形成連續(xù)地址空間,這種分配內(nèi)存方式成為“指針碰撞”,但是很明顯,這種方式也存在一個(gè)比較嚴(yán)重的問(wèn)題,那就是多線程創(chuàng)建對(duì)象時(shí),會(huì)導(dǎo)致指針劃分不一致的問(wèn)題,例如A線程剛剛將指針移動(dòng)到新位置,但是B線程之前讀取到的是指針之前的位置,這樣劃分內(nèi)存時(shí)就出現(xiàn)不一致的問(wèn)題,解決這種問(wèn)題,虛擬機(jī)采用了循環(huán)CAS操作來(lái)保證內(nèi)存的正確劃分;
(2)第二種也是為了解決第一種分配方式的不足而創(chuàng)建的方式,多線程分配內(nèi)存時(shí),虛擬機(jī)為每個(gè)線程分配了不同的空間,這樣每個(gè)線程在分配內(nèi)存時(shí)只是在自己的空間中操作,從而避免了上述問(wèn)題,不需要同步。當(dāng)然,當(dāng)線程自己的空間用完了才需要需申請(qǐng)空間,這時(shí)候需要進(jìn)行同步鎖定。為每個(gè)線程分配的空間稱(chēng)為“本地線程分配緩沖(TLAB)”,是否啟用TLAB需要通過(guò) -XX:+/-UseTLAB參數(shù)來(lái)設(shè)定。
第三步,分配完內(nèi)存后,需要對(duì)對(duì)象的字段進(jìn)行零值初始化,對(duì)象頭除外,零值初始化意思就是對(duì)對(duì)象的字段賦0值,或者null值,這也就解釋了為什么這些字段在不需要進(jìn)程初始化時(shí)候就能直接使用;
第四步,這里,虛擬機(jī)需要對(duì)這個(gè)將要?jiǎng)?chuàng)建出來(lái)的對(duì)象,進(jìn)行信息標(biāo)記,包括是否為新生代/老年代,對(duì)象的哈希碼,元數(shù)據(jù)信息,這些標(biāo)記存放在對(duì)象頭信息中,對(duì)象頭非常復(fù)雜,這里不作解釋?zhuān)梢粤硇邪俣龋?/p>
第五步,也就是最后一步,執(zhí)行對(duì)象的構(gòu)造方法,這里做的操作才是程序員真正想做的操作,例如初始化其他對(duì)象啊等等操作,至此,對(duì)象創(chuàng)建成功。
這里其實(shí)講的比較粗淺,只是對(duì)象創(chuàng)建的大概過(guò)程,例如對(duì)象頭、類(lèi)的加載等等都是非常復(fù)雜的過(guò)程,我會(huì)在接下來(lái)解釋。
總結(jié)
到此這篇關(guān)于從匯編碼分析java對(duì)象的創(chuàng)建過(guò)程的文章就介紹到這了,更多相關(guān)從匯編碼分析java對(duì)象的創(chuàng)建過(guò)程內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot使用Redis實(shí)現(xiàn)分布式緩存
這篇文章主要介紹了SpringBoot redis分布式緩存實(shí)現(xiàn)過(guò)程解析,文中通過(guò)示例代碼解析的非常詳細(xì),感興趣的同學(xué)可以參考閱讀2023-04-04
SpringMVC源碼解讀之 HandlerMapping - AbstractDetectingUrlHandlerM
這篇文章主要介紹了SpringMVC源碼解讀之 HandlerMapping - AbstractDetectingUrlHandlerMapping系列初始化的相關(guān)資料,需要的朋友可以參考下2016-02-02
Eclipse項(xiàng)目怎么導(dǎo)入IDEA并運(yùn)行(超詳細(xì))
這篇文章主要介紹了Eclipse項(xiàng)目怎么導(dǎo)入IDEA并運(yùn)行(超詳細(xì)),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-10-10
Java實(shí)現(xiàn)把excel xls中數(shù)據(jù)轉(zhuǎn)為可直接插入數(shù)據(jù)庫(kù)的sql文件
這篇文章主要介紹了Java實(shí)現(xiàn)把excel xls中數(shù)據(jù)轉(zhuǎn)為可直接插入數(shù)據(jù)庫(kù)的sql文件 的相關(guān)資料,需要的朋友可以參考下2016-03-03
Java實(shí)現(xiàn)從數(shù)據(jù)庫(kù)導(dǎo)出大量數(shù)據(jù)記錄并保存到文件的方法
這篇文章主要介紹了Java實(shí)現(xiàn)從數(shù)據(jù)庫(kù)導(dǎo)出大量數(shù)據(jù)記錄并保存到文件的方法,涉及Java針對(duì)數(shù)據(jù)庫(kù)的讀取及文件寫(xiě)入等操作技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-11-11
詳解java實(shí)現(xiàn)遍歷二叉樹(shù)的三種情況
這篇文章主要介紹了java實(shí)現(xiàn)遍歷二叉樹(shù)的三種情況,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-04-04
jquery對(duì)輸入框內(nèi)容的數(shù)字校驗(yàn)代碼實(shí)例
這篇文章主要介紹了jquery對(duì)輸入框內(nèi)容的數(shù)字校驗(yàn)代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-09-09
mybatis foreach 循環(huán) list(map)實(shí)例
這篇文章主要介紹了mybatis foreach 循環(huán) list(map)實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-03-03

