中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

java對象的內存布局分為哪幾個區域

發布時間:2021-08-20 03:08:57 來源:億速云 閱讀:174 作者:chen 欄目:云計算

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

HotSpot虛擬機中,對象在內存中的布局分為三塊區域:對象頭、實例數據和對齊填充。

1)對象頭:包括標記字段和類型指針兩部分內容(注:如果是數組對象,則包含三部分內容):

1)Mark Word(標記字段):用于存儲運行時對象自身的數據。
	1>占用內存大小與虛擬機位長一致,在運行期間,考慮到JVM的空間效率,Mark Word被設計成為一個非固定的數據結構,以便存儲更多有效的數據。
	2>存儲運行時對象自身的數據:
	
		哈希碼(hash)
		GC分代年齡(age)
		鎖標識位:
			01	無鎖
			01	偏向鎖
			00	輕量級鎖
			10	重量級鎖
		偏向鎖標識位(biased_lock)
			0	無鎖
			1	偏向鎖
		偏向線程ID(JavaThread*)
		偏向時間戳(epoch)
		
		說明:鎖標識位、偏向鎖標識位、偏向線程ID等的具體實現均是在monitor對象中完成的。(源碼中的ObjectMonitor對象)
	
	3>Mark Word里存儲的數據會隨著鎖標志位的變化而變化,即不同的鎖狀態,存儲著不同的數據:
	
		鎖狀態		存儲內容							鎖標識位		偏向鎖標識位(是否是偏向鎖)		
		--------	------------------------------		--------		--------
		無鎖狀態	哈希碼、GC分代年齡					01				0
		偏向鎖		線程ID、偏向時間戳、GC分代年齡		01				1
		輕量級鎖	指向棧中鎖記錄的指針  				00				無
		重量級鎖	指向monitor的指針					10				無
		GC標記		無								11				無

2)Class Metadata Address(類型指針):指向對象的類元數據(方法區的Class數據),虛擬機通過這個指針確定該對象是哪個類的實例。

3)如果對象是數組類型,則對象頭中還存儲著數組的長度。

2)實例數據:存放類的屬性數據信息,包括父類的屬性信息。

3)對齊填充:由于虛擬機要求對象起始地址必須是8字節的整數倍,填充數據不是必須存在的,僅僅是為了字節對齊。

4)使用JOL(Java Object Layout)工具查看java對象的內存布局:

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];

	        // 查看對象內存布局
	        System.out.println(ClassLayout.parseInstance(testClassObj).toPrintable());
	    }
	}	


結果:
	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(標記字段)
		第5行:		類型指針
		第6行:		數組長度
	實例數據:
		第7行:		數組中存儲了5個TestClass對象的引用(開啟指針壓縮后,類型引用占4個字節),故占用5*4=20個字節。
	對齊填充:
		第8行:		對象頭+實例數據 占用的內存為36字節(不是8的整數倍),故需要4字節的對齊填充。

	對象占用的總空間:
		第9行

	內存浪費的總空間:
		第10行:		對齊填充消耗了4個字節。

		說明:若數組的長度改為6,則 對象頭+實例數據 占用的內存為40字節(8的整數倍),故不會出現對齊填充:

		[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 total

5)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對象的內存布局分為哪幾個區域”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

诸城市| 渭源县| 镇平县| 启东市| 攀枝花市| 南汇区| 高州市| 裕民县| 永清县| 邢台市| 介休市| 澄城县| 朝阳区| 黎平县| 长丰县| 宁武县| 伽师县| 神农架林区| 屏南县| 玛纳斯县| 兴山县| 青冈县| 安乡县| 博客| 锡林郭勒盟| 轮台县| 达尔| 朝阳市| 青阳县| 祁东县| 沁阳市| 丹江口市| 上思县| 兴宁市| 郁南县| 山东省| 丹棱县| 津市市| 鄄城县| 收藏| 湖北省|