JVM-對(duì)象內(nèi)存布局

jvm-對(duì)象內(nèi)存布局

對(duì)象內(nèi)存結(jié)構(gòu)概述

對(duì)象的創(chuàng)建過(guò)程:

  1. jvm將對(duì)象所在的class文件加載到方法區(qū)中
  2. jvm讀取main方法入口逛艰,將main方法入棧诈茧,執(zhí)行創(chuàng)建對(duì)象代碼
  3. 在main方法的棧內(nèi)存中分配對(duì)象的引用,在堆中分配內(nèi)存放入創(chuàng)建的對(duì)象云挟,并將棧中的引用指向堆中的對(duì)象

堆內(nèi)存中的對(duì)象由3部分組成:

  1. 對(duì)象頭 header
  2. 實(shí)例數(shù)據(jù) instance data
  3. 對(duì)齊填充字節(jié) padding

對(duì)象頭

對(duì)象頭存儲(chǔ)的是對(duì)象在運(yùn)行時(shí)狀態(tài)的相關(guān)信息姑原、指向該對(duì)象所屬類(lèi)的元數(shù)據(jù)的指針岭妖,如果對(duì)象是數(shù)組對(duì)象那么還會(huì)額外存儲(chǔ)對(duì)象的數(shù)組長(zhǎng)度

對(duì)象頭的組成

普通對(duì)象:

  1. 標(biāo)記字 mark word
  2. 指針類(lèi)型 klass pointer

數(shù)組對(duì)象:

  1. 標(biāo)記字 mark word
  2. 指針類(lèi)型 klass pointer
  3. 數(shù)組長(zhǎng)度

mark word

在對(duì)象頭中徽曲,mark word 一共有64個(gè)bit零截,用于存儲(chǔ)對(duì)象自身的運(yùn)行時(shí)數(shù)據(jù),標(biāo)記對(duì)象處于以下5種狀態(tài)中的某一種:

(此處應(yīng)有圖)

在mark word中秃臣,鎖(lock)標(biāo)志位占用2個(gè)bit涧衙,結(jié)合1個(gè)bit偏向鎖(biased_lock)標(biāo)志位,這樣通過(guò)倒數(shù)的3位甜刻,就能用來(lái)標(biāo)識(shí)當(dāng)前對(duì)象持有的鎖的狀態(tài)绍撞,并判斷出其余位存儲(chǔ)的是什么信息。


基于mark word的鎖升級(jí)流程:

無(wú)鎖/可偏向

鎖對(duì)象剛創(chuàng)建時(shí)得院,沒(méi)有任何線程競(jìng)爭(zhēng)傻铣,對(duì)象處于無(wú)鎖狀態(tài)。在上面打印的空對(duì)象的內(nèi)存布局中祥绞,根據(jù)大小端非洲,最后3位001,表示處于無(wú)鎖態(tài)蜕径,并且處于不可偏向狀態(tài)两踏。這是因?yàn)樵趈dk中偏向鎖存在延遲4秒啟動(dòng),也就是說(shuō)在jvm啟動(dòng)后4秒后創(chuàng)建的對(duì)象才會(huì)開(kāi)啟偏向鎖兜喻,我們通過(guò)jvm參數(shù)-XX:BiasedLockingStartupDelay=0取消這個(gè)延遲時(shí)間梦染,這時(shí)最后3位為101,表示當(dāng)前對(duì)象的鎖沒(méi)有被持有朴皆,并且處于可被偏向狀態(tài)帕识。

偏向鎖

在沒(méi)有線程競(jìng)爭(zhēng)的條件下,第一個(gè)獲取鎖的線程通過(guò)CAS將自己的threadId寫(xiě)入到該對(duì)象的mark word中遂铡,若后續(xù)該線程再次獲取鎖肮疗,需要比較當(dāng)前線程threadId和對(duì)象mark word中的threadId是否一致,如果一致那么可以直接獲取扒接,并且鎖對(duì)象始終保持對(duì)該線程的偏向伪货,也就是說(shuō)偏向鎖不會(huì)主動(dòng)釋放。
偏向鎖的CAS環(huán)節(jié)在修改thread id

無(wú)鎖和偏向鎖狀態(tài)時(shí)钾怔,偏向鎖標(biāo)記位是有值的碱呼,所以看后三位

輕量級(jí)鎖

當(dāng)兩個(gè)或以上線程交替獲取鎖,但并沒(méi)有在對(duì)象上并發(fā)的獲取鎖時(shí)宗侦,偏向鎖升級(jí)為輕量級(jí)鎖巍举。在此階段,線程采取CAS的自旋方式嘗試獲取鎖凝垛,避免阻塞線程造成的cpu在用戶(hù)態(tài)和內(nèi)核態(tài)間轉(zhuǎn)換的消耗懊悯。
輕量級(jí)鎖的CAS環(huán)節(jié)在自旋獲取鎖

輕量級(jí)鎖和重量級(jí)鎖時(shí)蜓谋,已不需要偏向鎖標(biāo)記,所以只有后兩位

綜合上面3個(gè)階段炭分,整個(gè)加鎖狀態(tài)的變化流程如下:

  1. 主線程首先對(duì)user對(duì)象加鎖桃焕,首次加鎖為101偏向鎖
  2. 子線程等待主線程釋放鎖后,對(duì)user對(duì)象加鎖捧毛,這時(shí)將偏向鎖升級(jí)為00輕量級(jí)鎖
  3. 輕量級(jí)鎖解鎖后观堂,user對(duì)象無(wú)線程競(jìng)爭(zhēng),恢復(fù)為001無(wú)鎖態(tài)呀忧,并且處于不可偏向狀態(tài)师痕。如果之后有線程再?lài)L試獲取user對(duì)象的鎖,會(huì)直接加輕量級(jí)鎖而账,而不是偏向鎖

重量級(jí)鎖

當(dāng)兩個(gè)或以上線程并發(fā)的在同一個(gè)對(duì)象上進(jìn)行同步時(shí)胰坟,為了避免無(wú)用自旋消耗cpu,輕量級(jí)鎖會(huì)升級(jí)成重量級(jí)鎖泞辐。這時(shí)mark word中的指針指向的是monitor對(duì)象(也被稱(chēng)為管程或監(jiān)視器鎖)的起始地址笔横。在兩個(gè)線程同時(shí)競(jìng)爭(zhēng)user對(duì)象的鎖時(shí),會(huì)升級(jí)為10重量級(jí)鎖咐吼。

mark word中的其他信息

hashcode

無(wú)鎖態(tài)下的hashcode采用了延遲加載技術(shù)吹缔,在第一次調(diào)用hashCode()方法時(shí)才會(huì)計(jì)算寫(xiě)入。

只有在調(diào)用沒(méi)有被重寫(xiě)的Object.hashCode()方法或System.identityHashCode(Object)方法才會(huì)寫(xiě)入mark word锯茄,執(zhí)行用戶(hù)自定義的hashCode()方法不會(huì)被寫(xiě)入厢塘。

當(dāng)對(duì)象被加鎖后,mark word中就沒(méi)有足夠空間來(lái)保存hashCode了肌幽,這時(shí)hashcode會(huì)被移動(dòng)到重量級(jí)鎖的Object Monitor中晚碾。

epoch

偏向鎖的時(shí)間戳

分代年齡(age)

在jvm的垃圾回收過(guò)程中,每當(dāng)對(duì)象經(jīng)過(guò)一次Young GC牍颈,年齡都會(huì)加1,這里4位來(lái)表示分代年齡最大值為15琅关,這也就是為什么對(duì)象的年齡超過(guò)15后會(huì)被移到老年代的原因煮岁。在啟動(dòng)時(shí)可以通過(guò)添加參數(shù)來(lái)改變年齡閾值-XX:MaxTenuringThreshold,當(dāng)設(shè)置的閾值超過(guò)15時(shí)涣易,啟動(dòng)時(shí)會(huì)報(bào)錯(cuò)画机。

Klass Pointer 類(lèi)型指針

Klass Pointer是一個(gè)指向方法區(qū)中Class信息的指針,虛擬機(jī)通過(guò)這個(gè)指針確定該對(duì)象屬于哪個(gè)類(lèi)的實(shí)例新症。在64位的JVM中步氏,支持指針壓縮功能,根據(jù)是否開(kāi)啟指針壓縮徒爹,Klass Pointer占用的大小將會(huì)不同:

  1. 未開(kāi)啟指針壓縮時(shí)荚醒,類(lèi)型指針占用8B (64bit)
  2. 開(kāi)啟指針壓縮情況下芋类,類(lèi)型指針占用4B (32bit)

在jdk6之后的版本中,指針壓縮是被默認(rèn)開(kāi)啟的

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

實(shí)例數(shù)據(jù)存儲(chǔ)的是對(duì)象的真正有效數(shù)據(jù)界阁,也就是各個(gè)屬性字段的值侯繁,如果在擁有父類(lèi)的情況下,還會(huì)包含父類(lèi)的字段泡躯。字段的存儲(chǔ)順序會(huì)受到數(shù)據(jù)類(lèi)型長(zhǎng)度贮竟、以及虛擬機(jī)的分配策略的影響

對(duì)齊填充字節(jié)

在java對(duì)象中,需要對(duì)齊填充字節(jié)的原因是较剃,64位的jvm中對(duì)象的大小被要求向8字節(jié)對(duì)齊咕别,因此當(dāng)對(duì)象的長(zhǎng)度不足8字節(jié)的整數(shù)倍時(shí),需要在對(duì)象中進(jìn)行填充操作写穴。注意圖中對(duì)齊填充部分使用了虛線惰拱,這是因?yàn)樘畛渥止?jié)并不是固定存在的部分,這點(diǎn)在后面計(jì)算對(duì)象大小時(shí)具體進(jìn)行說(shuō)明

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末确垫,一起剝皮案震驚了整個(gè)濱河市弓颈,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌删掀,老刑警劉巖翔冀,帶你破解...
    沈念sama閱讀 212,454評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異披泪,居然都是意外死亡纤子,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén)款票,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)控硼,“玉大人,你說(shuō)我怎么就攤上這事艾少】ㄇ” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,921評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵缚够,是天一觀的道長(zhǎng)幔妨。 經(jīng)常有香客問(wèn)我,道長(zhǎng)谍椅,這世上最難降的妖魔是什么误堡? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,648評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮雏吭,結(jié)果婚禮上锁施,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好悉抵,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,770評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布肩狂。 她就那樣靜靜地躺著,像睡著了一般基跑。 火紅的嫁衣襯著肌膚如雪婚温。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,950評(píng)論 1 291
  • 那天媳否,我揣著相機(jī)與錄音栅螟,去河邊找鬼。 笑死篱竭,一個(gè)胖子當(dāng)著我的面吹牛力图,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播掺逼,決...
    沈念sama閱讀 39,090評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼吃媒,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了吕喘?” 一聲冷哼從身側(cè)響起赘那,我...
    開(kāi)封第一講書(shū)人閱讀 37,817評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎氯质,沒(méi)想到半個(gè)月后募舟,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,275評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡闻察,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,592評(píng)論 2 327
  • 正文 我和宋清朗相戀三年拱礁,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片辕漂。...
    茶點(diǎn)故事閱讀 38,724評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡呢灶,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出钉嘹,到底是詐尸還是另有隱情鸯乃,我是刑警寧澤,帶...
    沈念sama閱讀 34,409評(píng)論 4 333
  • 正文 年R本政府宣布跋涣,位于F島的核電站缨睡,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏仆潮。R本人自食惡果不足惜宏蛉,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,052評(píng)論 3 316
  • 文/蒙蒙 一遣臼、第九天 我趴在偏房一處隱蔽的房頂上張望性置。 院中可真熱鬧,春花似錦揍堰、人聲如沸鹏浅。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,815評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)隐砸。三九已至之碗,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間季希,已是汗流浹背褪那。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,043評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留式塌,地道東北人博敬。 一個(gè)月前我還...
    沈念sama閱讀 46,503評(píng)論 2 361
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像峰尝,于是被迫代替她去往敵國(guó)和親偏窝。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,627評(píng)論 2 350

推薦閱讀更多精彩內(nèi)容