本篇內(nèi)容介紹了“java對象的內(nèi)存布局分為哪幾個區(qū)域”的有關(guān)知識,在實(shí)際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

南明網(wǎng)站制作公司哪家好,找成都創(chuàng)新互聯(lián)公司!從網(wǎng)頁設(shè)計(jì)、網(wǎng)站建設(shè)、微信開發(fā)、APP開發(fā)、響應(yīng)式網(wǎng)站建設(shè)等網(wǎng)站項(xiàng)目制作,到程序開發(fā),運(yùn)營維護(hù)。成都創(chuàng)新互聯(lián)公司自2013年起到現(xiàn)在10年的時間,我們擁有了豐富的建站經(jīng)驗(yàn)和運(yùn)維經(jīng)驗(yàn),來保證我們的工作的順利進(jìn)行。專注于網(wǎng)站建設(shè)就選成都創(chuàng)新互聯(lián)公司。
HotSpot虛擬機(jī)中,對象在內(nèi)存中的布局分為三塊區(qū)域:對象頭、實(shí)例數(shù)據(jù)和對齊填充。
1)對象頭:包括標(biāo)記字段和類型指針兩部分內(nèi)容(注:如果是數(shù)組對象,則包含三部分內(nèi)容):
1)Mark Word(標(biāo)記字段):用于存儲運(yùn)行時對象自身的數(shù)據(jù)。 1>占用內(nèi)存大小與虛擬機(jī)位長一致,在運(yùn)行期間,考慮到JVM的空間效率,Mark Word被設(shè)計(jì)成為一個非固定的數(shù)據(jù)結(jié)構(gòu),以便存儲更多有效的數(shù)據(jù)。 2>存儲運(yùn)行時對象自身的數(shù)據(jù): 哈希碼(hash) GC分代年齡(age) 鎖標(biāo)識位: 01 無鎖 01 偏向鎖 00 輕量級鎖 10 重量級鎖 偏向鎖標(biāo)識位(biased_lock) 0 無鎖 1 偏向鎖 偏向線程ID(JavaThread*) 偏向時間戳(epoch) 說明:鎖標(biāo)識位、偏向鎖標(biāo)識位、偏向線程ID等的具體實(shí)現(xiàn)均是在monitor對象中完成的。(源碼中的ObjectMonitor對象) 3>Mark Word里存儲的數(shù)據(jù)會隨著鎖標(biāo)志位的變化而變化,即不同的鎖狀態(tài),存儲著不同的數(shù)據(jù): 鎖狀態(tài) 存儲內(nèi)容 鎖標(biāo)識位 偏向鎖標(biāo)識位(是否是偏向鎖) -------- ------------------------------ -------- -------- 無鎖狀態(tài) 哈希碼、GC分代年齡 01 0 偏向鎖 線程ID、偏向時間戳、GC分代年齡 01 1 輕量級鎖 指向棧中鎖記錄的指針 00 無 重量級鎖 指向monitor的指針 10 無 GC標(biāo)記 無 11 無 2)Class Metadata Address(類型指針):指向?qū)ο蟮念愒獢?shù)據(jù)(方法區(qū)的Class數(shù)據(jù)),虛擬機(jī)通過這個指針確定該對象是哪個類的實(shí)例。 3)如果對象是數(shù)組類型,則對象頭中還存儲著數(shù)組的長度。
2)實(shí)例數(shù)據(jù):存放類的屬性數(shù)據(jù)信息,包括父類的屬性信息。
3)對齊填充:由于虛擬機(jī)要求對象起始地址必須是8字節(jié)的整數(shù)倍,填充數(shù)據(jù)不是必須存在的,僅僅是為了字節(jié)對齊。
4)使用JOL(Java Object Layout)工具查看java對象的內(nèi)存布局:
maven依賴:
<dependency>
<groupId>org.openjdk.jol</groupId>
<artifactId>jol-core</artifactId>
<version>0.14</version>
</dependency>
代碼:
public class TestClassLayout {
public static void main(String[] args) {
TestClass[] testClassObj = new TestClass[5];
// 查看對象內(nèi)存布局
System.out.println(ClassLayout.parseInstance(testClassObj).toPrintable());
}
}
結(jié)果:
1 [Lcom.jxn.test.TestClass; object internals:
2 OFFSET SIZE TYPE DESCRIPTION VALUE
3 0 4 (object header) 01 00 00 00 (00000001 00000000 00000000 00000000) (1)
4 4 4 (object header) 00 00 00 00 (00000000 00000000 00000000 00000000) (0)
5 8 4 (object header) 82 c1 00 f8 (10000010 11000001 00000000 11111000) (-134168190)
6 12 4 (object header) 05 00 00 00 (00000101 00000000 00000000 00000000) (5)
7 16 20 com.jxn.test.TestClass TestClass;.<elements> N/A
8 36 4 (loss due to the next object alignment)
9 Instance size: 40 bytes
10 Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
對象頭:
第3行+第4行: Mark Word(標(biāo)記字段)
第5行: 類型指針
第6行: 數(shù)組長度
實(shí)例數(shù)據(jù):
第7行: 數(shù)組中存儲了5個TestClass對象的引用(開啟指針壓縮后,類型引用占4個字節(jié)),故占用5*4=20個字節(jié)。
對齊填充:
第8行: 對象頭+實(shí)例數(shù)據(jù) 占用的內(nèi)存為36字節(jié)(不是8的整數(shù)倍),故需要4字節(jié)的對齊填充。
對象占用的總空間:
第9行
內(nèi)存浪費(fèi)的總空間:
第10行: 對齊填充消耗了4個字節(jié)。
說明:若數(shù)組的長度改為6,則 對象頭+實(shí)例數(shù)據(jù) 占用的內(nèi)存為40字節(jié)(8的整數(shù)倍),故不會出現(xiàn)對齊填充:
[Lcom.jxn.test.TestClass; object internals:
OFFSET SIZE TYPE DESCRIPTION VALUE
0 4 (object header) 01 00 00 00 (00000001 00000000 00000000 00000000) (1)
4 4 (object header) 00 00 00 00 (00000000 00000000 00000000 00000000) (0)
8 4 (object header) 82 c1 00 f8 (10000010 11000001 00000000 11111000) (-134168190)
12 4 (object header) 06 00 00 00 (00000110 00000000 00000000 00000000) (6)
16 24 com.jxn.test.TestClass TestClass;.<elements> N/A
Instance size: 40 bytes
Space losses: 0 bytes internal + 0 bytes external = 0 bytes total5)hotspot/src/share/vm/oops/markOop.hpp 源碼中的說明:
// The markOop describes the header of an object. // // Note that the mark is not a real oop but just a word. // It is placed in the oop hierarchy for historical reasons. // // Bit-format of an object header (most significant first, big endian layout below): // // 32 bits: // -------- // hash:25 ------------>| age:4 biased_lock:1 lock:2 (normal object) // JavaThread*:23 epoch:2 age:4 biased_lock:1 lock:2 (biased object) // size:32 ------------------------------------------>| (CMS free block) // PromotedObject*:29 ---------->| promo_bits:3 ----->| (CMS promoted object) // // 64 bits: // -------- // unused:25 hash:31 -->| unused:1 age:4 biased_lock:1 lock:2 (normal object) // JavaThread*:54 epoch:2 unused:1 age:4 biased_lock:1 lock:2 (biased object) // PromotedObject*:61 --------------------->| promo_bits:3 ----->| (CMS promoted object) // size:64 ----------------------------------------------------->| (CMS free block) // // unused:25 hash:31 -->| cms_free:1 age:4 biased_lock:1 lock:2 (COOPs && normal object) // JavaThread*:54 epoch:2 cms_free:1 age:4 biased_lock:1 lock:2 (COOPs && biased object) // narrowOop:32 unused:24 cms_free:1 unused:4 promo_bits:3 ----->| (COOPs && CMS promoted object) // unused:21 size:35 -->| cms_free:1 unused:7 ------------------>| (COOPs && CMS free block) // // - hash contains the identity hash value: largest value is // 31 bits, see os::random(). Also, 64-bit vm's require // a hash value no bigger than 32 bits because they will not // properly generate a mask larger than that: see library_call.cpp // and c1_CodePatterns_sparc.cpp. // // - the biased lock pattern is used to bias a lock toward a given // thread. When this pattern is set in the low three bits, the lock // is either biased toward a given thread or "anonymously" biased, // indicating that it is possible for it to be biased. When the // lock is biased toward a given thread, locking and unlocking can // be performed by that thread without using atomic operations. // When a lock's bias is revoked, it reverts back to the normal // locking scheme described below. // // Note that we are overloading the meaning of the "unlocked" state // of the header. Because we steal a bit from the age we can // guarantee that the bias pattern will never be seen for a truly // unlocked object. // // Note also that the biased state contains the age bits normally // contained in the object header. Large increases in scavenge // times were seen when these bits were absent and an arbitrary age // assigned to all biased objects, because they tended to consume a // significant fraction of the eden semispaces and were not // promoted promptly, causing an increase in the amount of copying // performed. The runtime system aligns all JavaThread* pointers to // a very large value (currently 128 bytes (32bVM) or 256 bytes (64bVM)) // to make room for the age bits & the epoch bits (used in support of // biased locking), and for the CMS "freeness" bit in the 64bVM (+COOPs). // // [JavaThread* | epoch | age | 1 | 01] lock is biased toward given thread // [0 | epoch | age | 1 | 01] lock is anonymously biased // // - the two lock bits are used to describe three states: locked/unlocked and monitor. // // [ptr | 00] locked ptr points to real header on stack // [header | 0 | 01] unlocked regular object header // [ptr | 10] monitor inflated lock (header is wapped out) // [ptr | 11] marked used by markSweep to mark an object not valid at any other time // // We assume that stack/thread pointers have the lowest two bits cleared.
“java對象的內(nèi)存布局分為哪幾個區(qū)域”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識可以關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!
網(wǎng)站名稱:java對象的內(nèi)存布局分為哪幾個區(qū)域
本文路徑:http://chinadenli.net/article2/gsjpic.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供品牌網(wǎng)站建設(shè)、企業(yè)網(wǎng)站制作、品牌網(wǎng)站制作、網(wǎng)站收錄、網(wǎng)站策劃、網(wǎng)站維護(hù)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)