一道阿里面試難題:如何計算JAVA對象大卸⒋氯檐?

在做JVM內(nèi)存調(diào)優(yōu)的時候,我們免不了需要去計算對象的大小体捏。計算對象大小又要考慮是普通對象還是數(shù)組對象冠摄,因為普通對象與數(shù)組對象的對象頭存在些許差異。而且自JDK6以后几缭,為了節(jié)省內(nèi)存河泳、提高運行效率,又引入了新的技術(shù):指針壓縮年栓。更加劇了計算對象大小的難度拆挥。

這篇文章就來深入分析如何計算對象大小,確保計算的結(jié)果與實際情況不差一個字節(jié)某抓。

對象結(jié)構(gòu)

對象結(jié)構(gòu)想必深入學(xué)習(xí)過JVM的人都知道竿刁,它分為三大部分:對象頭、實例數(shù)據(jù)搪缨、對齊填充。其中對象頭又分為三個部分:Mark Word鸵熟、類型指針副编、數(shù)組長度。其實對象頭還有第四部分流强,這是目前你看到的書痹届、視頻都沒有提到的呻待,對象頭也有對齊填充部分,這個部分也不是一定會有队腐,只有數(shù)組對象在未開啟指針壓縮的情況下才會出現(xiàn)蚕捉。是不是一臉懵,那就繼續(xù)往后看柴淘。

指針壓縮

看到這四個字是不是一堆的問號:這是什么迫淹?這怎么實現(xiàn)的?為什么說它節(jié)省了內(nèi)存为严?……咱們就來搞清楚這些個問題敛熬。

咱們先達(dá)成觀念上的一致:所有的對象都是以8字節(jié)對齊的。現(xiàn)在我有3個對象:test1(16字節(jié))第股、test2(32字節(jié))应民、test3(24字節(jié)),為了便于說明夕吻,假如這三個對象中間沒有其他對象诲锹,那他們的內(nèi)存地址是:

test1 = 0x0000 0 000(0字節(jié) ~ 16字節(jié))
test2 = 0x0001 0 000(16字節(jié) ~ 48字節(jié)) 
test3 = 0x0011 0 000(48字節(jié) ~ 72字節(jié))

大家發(fā)現(xiàn)規(guī)律了嗎,所有對象指針的后三位都是0涉馅,這就是指針壓縮的實現(xiàn)原理归园。開啟指針壓縮后,JVM會將對象指針的后三位給截去控漠,如果test2 = 0x10000蔓倍,在開啟指針后就變成了test2=0x10,在使用的時候?qū)⒑笕坏?補回去盐捷,即test2=0x10 000偶翅。

因為開啟了指針壓縮后,對象指針就變成了4字節(jié)(32位)碉渡,加上補3位聚谁,共35位。即開啟指針壓縮后一個對象指針能表示的最大堆空間是2的35次方滞诺,即32G形导。

那讀者可以想一想?如果我想擴充一個oop能表示的堆空間大小該怎么做呢习霹?

下面咱們來看四種情況(普通對象-關(guān)閉指針壓縮朵耕、普通對象-開啟指針壓縮、數(shù)組對象-關(guān)閉指針壓縮淋叶、數(shù)組對象-開啟指針壓縮)下的對象大小是如何計算出來的阎曹。建議讀者寫相似代碼測試一下,這樣才能理解得更深刻。\

測試代碼:

package com.qimingnan.adjust;

import org.openjdk.jol.info.ClassLayout;

public class Test1 {
    int a = 10;
    int b = 20;

    static int[] arr = {0, 1, 2};

    public static void main(String[] args) {
        Test1 test1 = new Test1();

        System.out.printf(ClassLayout.parseInstance(test1).toPrintable());
        System.out.printf(ClassLayout.parseInstance(arr).toPrintable());
    }
}

普通對象

一处嫌、未開啟指針壓縮

24B = 8B(Mark Word)+ 8B(KClass Pointer)+ 4B + 4B

二栅贴、開啟指針壓縮

24B = 8B(Mark Word)+ 4B(KClass Pointer)+ 4B(int a)+ 4B(int b)+ 4B(Padding)

數(shù)組對象

一、未開啟指針壓縮

40B = 8B(Mark Word)+ 8B(KClass Pointer)+ 4B(數(shù)組長度)+ 4B(頭部Padding)+ 12B(3個int)+ 4B(對象Padding)

二熏迹、開啟指針壓縮

32B = 8B(Mark Word)+ 4B(KClass Pointer)+ 4B(數(shù)組長度)+ 12B(3個int)+ 4B(對象Padding)

如何計算對象大小大家學(xué)會了嗎檐薯?

介紹一款工具,jol注暗,大家在做測試的時候可以借助這個工具

<dependency>
    <groupId>org.openjdk.jol</groupId>
    <artifactId>jol-core</artifactId>
    <version>0.10</version>
</dependency>

這篇文章有些地方可能不太好理解坛缕,讀者有問題的話,留言提問吧友存。我都會一一回復(fù)祷膳。

后續(xù)我將為大家新開《手寫JVM》的系列專欄,如果你對此感興趣的話屡立,那么就關(guān)注我吧直晨。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市膨俐,隨后出現(xiàn)的幾起案子勇皇,更是在濱河造成了極大的恐慌搁廓,老刑警劉巖冀宴,帶你破解...
    沈念sama閱讀 212,816評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異习贫,居然都是意外死亡乳愉,警方通過查閱死者的電腦和手機兄淫,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,729評論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蔓姚,“玉大人捕虽,你說我怎么就攤上這事∑缕辏” “怎么了泄私?”我有些...
    開封第一講書人閱讀 158,300評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長备闲。 經(jīng)常有香客問我晌端,道長,這世上最難降的妖魔是什么恬砂? 我笑而不...
    開封第一講書人閱讀 56,780評論 1 285
  • 正文 為了忘掉前任咧纠,我火速辦了婚禮,結(jié)果婚禮上泻骤,老公的妹妹穿的比我還像新娘惧盹。我一直安慰自己乳幸,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,890評論 6 385
  • 文/花漫 我一把揭開白布钧椰。 她就那樣靜靜地躺著,像睡著了一般符欠。 火紅的嫁衣襯著肌膚如雪嫡霞。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 50,084評論 1 291
  • 那天希柿,我揣著相機與錄音诊沪,去河邊找鬼。 笑死曾撤,一個胖子當(dāng)著我的面吹牛端姚,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播挤悉,決...
    沈念sama閱讀 39,151評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼渐裸,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了装悲?” 一聲冷哼從身側(cè)響起昏鹃,我...
    開封第一講書人閱讀 37,912評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎诀诊,沒想到半個月后洞渤,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,355評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡属瓣,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,666評論 2 327
  • 正文 我和宋清朗相戀三年载迄,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片抡蛙。...
    茶點故事閱讀 38,809評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡护昧,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出溜畅,到底是詐尸還是另有隱情捏卓,我是刑警寧澤,帶...
    沈念sama閱讀 34,504評論 4 334
  • 正文 年R本政府宣布慈格,位于F島的核電站怠晴,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏浴捆。R本人自食惡果不足惜蒜田,卻給世界環(huán)境...
    茶點故事閱讀 40,150評論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望选泻。 院中可真熱鬧冲粤,春花似錦美莫、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至傀顾,卻和暖如春襟铭,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背短曾。 一陣腳步聲響...
    開封第一講書人閱讀 32,121評論 1 267
  • 我被黑心中介騙來泰國打工寒砖, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人嫉拐。 一個月前我還...
    沈念sama閱讀 46,628評論 2 362
  • 正文 我出身青樓哩都,卻偏偏與公主長得像,于是被迫代替她去往敵國和親婉徘。 傳聞我的和親對象是個殘疾皇子漠嵌,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,724評論 2 351

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