在java中對(duì)象對(duì)于我們來(lái)說(shuō)再熟悉不過(guò)了,運(yùn)用也簡(jiǎn)單,什么時(shí)候想要new一個(gè),所以說(shuō)啊咱們程序員不缺對(duì)象!
那我們真的了解對(duì)象嗎?它由哪幾部分組成呢?
在HotSpot虛擬機(jī)中,也就是我們的常用虛擬機(jī)。對(duì)象組成分為3個(gè)區(qū)域:對(duì)象頭、實(shí)例數(shù)據(jù)、對(duì)齊填充。
對(duì)象頭
對(duì)象頭分為兩個(gè)部分:對(duì)象自身運(yùn)行時(shí)的數(shù)據(jù),類(lèi)型指針
對(duì)象自身運(yùn)行時(shí)的數(shù)據(jù),例如:HashCode、鎖狀態(tài)標(biāo)志、線程持有的鎖、偏向線程ID、偏向時(shí)間戳、GC分代年齡等。這部分?jǐn)?shù)據(jù)長(zhǎng)度在32位和64位虛擬機(jī)(若未開(kāi)啟壓縮指針)下分別為32bit和64bit。這部分稱(chēng)為"Mark Word"。
并且Mark Word 被設(shè)計(jì)為沒(méi)有固定的數(shù)據(jù)結(jié)構(gòu)用來(lái)在很小的空間內(nèi)可以存儲(chǔ)更多的信息,它會(huì)根據(jù)不同的狀態(tài)存儲(chǔ)不同的數(shù)據(jù)。例如在32位情況下,存儲(chǔ)內(nèi)容的變化如下
類(lèi)型指針,也就是指向此對(duì)象的類(lèi)元數(shù)據(jù)的指針,也就是通過(guò)這個(gè)指針來(lái)知道這個(gè)對(duì)象是哪個(gè)類(lèi)的實(shí)例,但是不是所有的虛擬機(jī)實(shí)現(xiàn)都是通過(guò)這個(gè)來(lái)查找類(lèi)的元數(shù)據(jù)的。
像HotSpot虛擬機(jī),我們都知道平時(shí)new了一個(gè)對(duì)象保存的是這個(gè)對(duì)象的引用,這個(gè)引用存儲(chǔ)的是對(duì)象實(shí)例的地址,而有些虛擬機(jī)的實(shí)現(xiàn)是這個(gè)引用存儲(chǔ)的是一個(gè)對(duì)象的句柄地址,句柄地址又包含了對(duì)象實(shí)例地址和對(duì)象類(lèi)型地址。
也就是這類(lèi)虛擬機(jī)有一個(gè)句柄池,句柄池內(nèi)部存儲(chǔ)了對(duì)象的實(shí)例數(shù)據(jù)地址和類(lèi)數(shù)據(jù)地址,所以這類(lèi)虛擬機(jī)可以直接通過(guò)句柄池中類(lèi)數(shù)據(jù)地址去找到這個(gè)對(duì)象是屬于哪個(gè)類(lèi)的實(shí)例。
如果對(duì)象是個(gè)數(shù)組,那還需要一塊地方來(lái)記錄數(shù)據(jù)的長(zhǎng)度。
實(shí)例數(shù)據(jù)
實(shí)例數(shù)據(jù)就是對(duì)象真正存儲(chǔ)的數(shù)據(jù)區(qū),各種類(lèi)型的字段內(nèi)容。
對(duì)齊填充
這部分內(nèi)容沒(méi)什么別的意義,就是起著占位符的作用,主要是因?yàn)镠otSpot虛擬機(jī)的內(nèi)存管理要求對(duì)象的大小必須是8字節(jié)的整數(shù)倍,而對(duì)象頭正好是8個(gè)字節(jié)的整數(shù)倍,但是實(shí)例數(shù)據(jù)不一定,所以需要對(duì)齊填充補(bǔ)全。
如有錯(cuò)誤歡迎指正!
個(gè)人公眾號(hào):yes的練級(jí)攻略