自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

深入理解 Java 對象的內(nèi)存布局

開發(fā) 前端
本篇文章我們介紹了 Java 對象在 JVM 中的內(nèi)存布局,整體可以分為:對象頭、實例數(shù)據(jù)、對齊填充三個部分。

對于 Java 虛擬機(jī),我們都知道其內(nèi)存區(qū)域劃分成:堆、方法區(qū)、虛擬機(jī)棧等區(qū)域。但一個對象在 Java 虛擬機(jī)中是怎樣存儲的,相信很少人會比較清楚地了解。Java 對象在 JVM 中的內(nèi)存布局,是我們了解并發(fā)編程同步機(jī)制的基礎(chǔ)。

在 HotSpot 虛擬機(jī)中,對象在內(nèi)存中存儲的布局可以分為 3 塊區(qū)域:對象頭(Header)、實例數(shù)據(jù)(Instance Data)和對齊填充(Padding)。

對象頭

HotSpot 虛擬機(jī)的對象頭包括兩部分信息,第一部分用于存儲自身運行時的數(shù)據(jù),第二部分用于存儲類型指針。

自身運行時數(shù)據(jù)

對象頭第一部分用于存儲對象自身的運行時數(shù)據(jù),如哈希碼(HashCode)、GC 分代年齡、鎖狀態(tài)標(biāo)志、線程持有的鎖、偏向線程 ID、偏向時間戳等。這部分?jǐn)?shù)據(jù)的長度在 32 位和 64 位的虛擬機(jī)中分別為 32bit 和 64bit,官方稱它為「Mark Word」。

為了提高虛擬機(jī)的空間效率,Mark Word 被設(shè)計成非固定的數(shù)據(jù)結(jié)構(gòu),從而可以在不同狀態(tài)時存儲不同的數(shù)據(jù),從而達(dá)到節(jié)省數(shù)據(jù)空間的目的。Mark Word 在不同狀態(tài)下存儲的內(nèi)容如下表格所示。

圖片

Java 對象的內(nèi)存布局

如上表所示,在 32 位的 HotSpot 虛擬機(jī)中,如果對象處于未被鎖定(標(biāo)志位為 01)的狀態(tài)下,那么 Mark Word 存儲的就是「對象哈希碼、對象分代年齡」。32bit 空間中的 25bit 用于存儲對象哈希碼,4bit 用于存儲對象分代年齡,2bit 用于存儲鎖標(biāo)志位,1bit 固定為 0。

類型指針

對象頭第二部分是類型指針,即對象指向它的類元數(shù)據(jù)的指針,虛擬機(jī)通過這個指針來確定這個對象是哪個類的實例。 另外,如果對象是一個 Java 數(shù)組,那在對象頭中還必須有一塊用于記錄數(shù)組長度的數(shù)據(jù),因為虛擬機(jī)可以通過普通 Java 對象的元數(shù)據(jù)信息確定 Java 對象的大小,但是從數(shù)組的元數(shù)據(jù)中卻無法確定數(shù)組的大小。

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

實例數(shù)據(jù)部分是對象真正存儲的有效信息,包括了程序里各個類型的字段類型,無論是父類繼承下來的,還是子類中定義的。一般來說,父類定義的變量總會出現(xiàn)在子類之前。

對齊填充

對象填充部分并不是必然存在的,也沒有特別的含義,它僅僅起著占位符的作用。由于 HotSpot VM 的自動內(nèi)存管理系統(tǒng)要求對象起始地址必須是 8 字節(jié)的整數(shù)倍,換句話說,就是對象的大小必須是 8 字節(jié)的整數(shù)倍。而對象頭部分正好是 8 字節(jié)的倍數(shù)(1 倍或者 2 倍),因此,當(dāng)對象實例數(shù)據(jù)部分沒有對齊時,就需要通過對齊填充來補(bǔ)全。

總結(jié)

本篇文章我們介紹了 Java 對象在 JVM 中的內(nèi)存布局,整體可以分為:對象頭、實例數(shù)據(jù)、對齊填充三個部分。

第一部分的對象頭包括了對象運行時數(shù)據(jù)和類型指針。其中對象運行時數(shù)據(jù)包括:哈希碼、GC 分代年齡、鎖狀態(tài)標(biāo)志等,類型指針指向?qū)ο箢愋驮獢?shù)據(jù),確定對象是哪個類的實例。

第二部分是實例數(shù)據(jù),是真正存儲的有效信息,包括各個類型的字段。第三部分是對齊填充,因為 JVM 要求對象起始地址必須是 8 字節(jié)的整數(shù)倍,所以必須有對齊填充來占位。

圖片深入理解 Java 對象的內(nèi)存布局

責(zé)任編輯:武曉燕 來源: 陳樹義
相關(guān)推薦

2024-07-25 14:18:29

2023-09-19 22:47:39

Java內(nèi)存

2023-11-05 12:05:35

JVM內(nèi)存

2017-03-27 09:36:20

Flex布局計算

2012-02-14 10:29:02

Java

2021-11-26 00:00:48

JVM內(nèi)存區(qū)域

2020-11-04 15:35:13

Golang內(nèi)存程序員

2013-06-20 10:25:56

2017-12-18 16:33:55

多線程對象模型

2018-03-14 15:20:05

Java多線程勘誤

2015-03-24 13:28:52

Java Java Strin內(nèi)存模型

2022-06-22 08:02:11

CPU操作系統(tǒng)Java

2022-08-21 16:52:27

Linux虛擬內(nèi)存

2024-04-10 07:40:45

Java虛擬機(jī)內(nèi)存

2015-12-28 11:41:57

JVM內(nèi)存區(qū)域內(nèi)存溢出

2020-07-21 08:26:08

SpringSecurity過濾器

2016-12-08 15:36:59

HashMap數(shù)據(jù)結(jié)構(gòu)hash函數(shù)

2010-06-01 15:25:27

JavaCLASSPATH

2012-11-22 10:11:16

LispLisp教程

2020-09-25 07:55:51

內(nèi)存Java對象
點贊
收藏

51CTO技術(shù)棧公眾號