Java虛擬機(jī)--對象內(nèi)存布局

文末有彩蛋?。。。。。?/p>

對象中的數(shù)據(jù)

前兩篇,我們講到了Java對象的類加載Java對象的初始化操作。本篇,我們來繼續(xù)學(xué)習(xí)Java對象,看看Java對象在內(nèi)存中如何布局,看看Java對象中由哪些數(shù)據(jù)構(gòu)成,以及教給大家如何測量一個對象的大小。

HotSpot虛擬機(jī)下,一個對象在內(nèi)存中包含了3大區(qū)域,分別為:對象頭(Header)、實(shí)例數(shù)據(jù)(Instance Data)和對齊填充(Padding)。

對象頭(Header)

對象頭,顧名思義就是對象的頭部。如果按照一個團(tuán)隊(duì)來看,對象頭就好比團(tuán)隊(duì)中的領(lǐng)導(dǎo)。對于一個團(tuán)隊(duì)來說,領(lǐng)導(dǎo)至關(guān)重要。對于一個對象來說,對象頭不可或缺。

在計(jì)算機(jī)領(lǐng)域中,很多知識概念都有的存在,例如:Http請求頭。

在HotSpot虛擬機(jī)中,對象頭包括兩部分:Mark Word類型指針

那么,什么是Mark Word呢?什么是類型指針呢?

(1)Mark Word

Mark Word直譯為標(biāo)記字段,主要用于存儲對象自身的運(yùn)行時(shí)數(shù)據(jù),如哈希碼(HashCode)、GC分代年齡、鎖狀態(tài)標(biāo)志、線程持有的鎖、偏向線程ID、偏向時(shí)間戳等。

在不同的運(yùn)行環(huán)境中,所占用內(nèi)存的大小也不盡相同。在32位的機(jī)器中,Mark Word大小為32bit,4字節(jié)。在64位機(jī)器中,Mark Word大小為64bit,也就是8字節(jié)。

考慮到虛擬機(jī)的存儲空間,Mark Word被設(shè)計(jì)成一個非固定的數(shù)據(jù)結(jié)構(gòu)以便在最小的內(nèi)存中存儲更多的有用信息。

對于Mark Work來說,在不同場景下存儲著不一樣的信息。例如:在32位計(jì)算機(jī)中,如果一個對象處于未鎖定(沒有被加鎖)狀態(tài)下,那么該對象的Mard Word大小為32bit,其中25bit用戶存儲對象哈希碼,4bit用于存儲對象分代年齡,2bit用于存儲鎖標(biāo)志位,1bit固定為0。

而其他場景如下:

場景 存儲內(nèi)容 鎖標(biāo)志位
未加鎖 對象哈希碼、對象分代年齡 01
輕量級鎖定 指向鎖記錄的指針 00
重量級鎖定 指向重量級鎖的指針 10
GC標(biāo)記 不需要記錄任何信息 11
偏向鎖 偏向線程ID、偏向時(shí)間戳、對象分代年齡 01

可以看出,在不同場景下,Mark Word中存儲的數(shù)據(jù)是不一樣的。要注意的是,當(dāng)一個對象從未加鎖狀態(tài)轉(zhuǎn)向其他狀態(tài)時(shí),原有的存儲內(nèi)容并不會丟失、被覆蓋,而是在當(dāng)前線程的棧幀中建立一個名為鎖記錄(Lock Record)的空間,用于存儲鎖對象目前的Mark Word的拷貝。

對于想要了解鎖機(jī)制的朋友,首先需要對Mark Word有所了解,鎖的實(shí)現(xiàn)離不開Mark Word。關(guān)于鎖的內(nèi)容,會在后面的多線程中進(jìn)行講解。

(2)類型指針

類型指針:對象指向其類元數(shù)據(jù)的指針,虛擬機(jī)通過這個指針確定該對象是哪個類的實(shí)例。

值得注意的是,如果對象是一個Java數(shù)組,那在對象頭中還必須有一塊區(qū)域用于記錄數(shù)組的長度,因?yàn)樘摂M機(jī)可以通過普通Java對象的元數(shù)據(jù)信息確定Java對象的大小,但是從數(shù)組的元數(shù)據(jù)中無法確定數(shù)組的大小。

實(shí)例數(shù)據(jù)(Instance Data)

實(shí)例數(shù)據(jù)部分,存儲著對象真正的有效信息,也就是代碼中定義的各種類型字段內(nèi)容。無論是父類繼承下來的,還是子類中自己定義的,都會在實(shí)例數(shù)據(jù)中保存起來。

實(shí)例數(shù)據(jù)的保存順序,跟代碼中定義的順序有較大的關(guān)系,通常情況下父類中定義的變量會排在子類之前。

原生類型(primitive type)的內(nèi)存占用如下:

原生類型 占用內(nèi)存大小(字節(jié))
boolean 1
byte 1
short 2
char 2
int 4
float 4
long 8
double 8
reference 4/8

對齊填充(Padding)

對齊填充,主要起到補(bǔ)全的作用。在HotSpot VM中,要求對象的大小必須是8字節(jié)的整數(shù)倍,當(dāng)對象頭+實(shí)例數(shù)據(jù)的大小不滿足此要求時(shí),就用到對齊填充來進(jìn)行補(bǔ)全。

bat面試寶典

京東購買鏈接:可伸縮服務(wù)架構(gòu)-框架與中間件

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容