最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

淺談java object對(duì)象在heap中的結(jié)構(gòu)

 更新時(shí)間:2021年06月02日 15:04:32   作者:flydean  
本文主要介紹了淺談java object對(duì)象在heap中的結(jié)構(gòu),感興趣的同學(xué),可以參考下。

對(duì)象和其隱藏的秘密

java.lang.Object大家應(yīng)該都很熟悉了,Object是java中一切對(duì)象的鼻祖。

接下來(lái)我們來(lái)對(duì)這個(gè)java對(duì)象的鼻祖進(jìn)行一個(gè)詳細(xì)的解剖分析,從而理解JVM的深層次的秘密。

工具當(dāng)然是使用JOL:

@Slf4j
public class JolUsage {

    @Test
    public void useJol(){
        log.info("{}", VM.current().details());
        log.info("{}", ClassLayout.parseClass(Object.class).toPrintable());
        log.info("{}", ClassLayout.parseInstance(new Object()).toPrintable());
    }
}

代碼很簡(jiǎn)單,我們打印JVM的信息,Object class和一個(gè)新的Object實(shí)例的信息。

看下輸出:

[main] INFO com.flydean.JolUsage - # Running 64-bit HotSpot VM.

# Using compressed oop with 3-bit shift.

# Using compressed klass with 3-bit shift.

# WARNING | Compressed references base/shifts are guessed by the experiment!

# WARNING | Therefore, computed addresses are just guesses, and ARE NOT RELIABLE.

# WARNING | Make sure to attach Serviceability Agent to get the reliable addresses.

# Objects are 8 bytes aligned.

# Field sizes by type: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes]

# Array element sizes: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes]

10:27:32.311 [main] INFO com.flydean.JolUsage - java.lang.Object object internals:

 OFFSET  SIZE   TYPE DESCRIPTION                               VALUE

      0    12        (object header)                           N/A

     12     4        (loss due to the next object alignment)

Instance size: 16 bytes

Space losses: 0 bytes internal + 4 bytes external = 4 bytes total

10:27:32.312 [main] INFO com.flydean.JolUsage - java.lang.Object object internals:

 OFFSET  SIZE   TYPE DESCRIPTION                               VALUE

      0     4        (object header)                           05 00 00 00 (00000101 00000000 00000000 00000000) (5)

      4     4        (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)

      8     4        (object header)                           86 06 00 00 (10000110 00000110 00000000 00000000) (1670)

     12     4        (loss due to the next object alignment)

Instance size: 16 bytes

Space losses: 0 bytes internal + 4 bytes external = 4 bytes total3

從上面的結(jié)果我們知道,在64位的JVM中,一個(gè)Object實(shí)例是占用16個(gè)字節(jié)。

因?yàn)镺bject對(duì)象中并沒(méi)有其他對(duì)象的引用,所以我們看到Object對(duì)象只有一個(gè)12字節(jié)的對(duì)象頭。剩下的4個(gè)字節(jié)是填充位。

Object對(duì)象頭

那么這12字節(jié)的對(duì)象頭是做什么用的呢?

如果想要深入了解這12字節(jié)的對(duì)象頭,當(dāng)然是要去研讀一下JVM的源碼:src/share/vm/oops/markOop.hpp。

有興趣的小伙伴可以去看看。如果沒(méi)有興趣,沒(méi)關(guān)系,這里給大家一個(gè)張總結(jié)的圖:

javaObject對(duì)象的對(duì)象頭大小根據(jù)你使用的是32位還是64位的虛擬機(jī)的不同,稍有變化。這里我們使用的是64位的虛擬機(jī)為例。

Object的對(duì)象頭,分為兩部分,第一部分是Mark Word,用來(lái)存儲(chǔ)對(duì)象的運(yùn)行時(shí)數(shù)據(jù)比如:hashcode,GC分代年齡,鎖狀態(tài),持有鎖信息,偏向鎖的thread ID等等。

在64位的虛擬機(jī)中,Mark Word是64bits,如果是在32位的虛擬機(jī)中Mark Word是32bits。

第二部分就是Klass Word,Klass Word是一個(gè)類型指針,指向class的元數(shù)據(jù),JVM通過(guò)Klass Word來(lái)判斷該對(duì)象是哪個(gè)class的實(shí)例。

且慢!

有的小伙伴可能發(fā)現(xiàn)了問(wèn)題,之前我們用JOL解析Object對(duì)象的時(shí)候,Object head大小是12字節(jié),也就是96bits,這里怎么寫(xiě)的是128bits?

沒(méi)錯(cuò),如果沒(méi)有開(kāi)啟COOPs就是128bits,如果開(kāi)啟了COOPs,那么Klass Word的大小就從64bits降到了32bits。

還記得我們之前講的COOPs嗎?

COOPs就是壓縮對(duì)象指針技術(shù)。

對(duì)象指針用來(lái)指向一個(gè)對(duì)象,表示對(duì)該對(duì)象的引用。通常來(lái)說(shuō)在64位機(jī)子上面,一個(gè)指針占用64位,也就是8個(gè)字節(jié)。而在32位機(jī)子上面,一個(gè)指針占用32位,也就是4個(gè)字節(jié)。

實(shí)時(shí)上,在應(yīng)用程序中,這種對(duì)象的指針是非常非常多的,從而導(dǎo)致如果同樣一個(gè)程序,在32位機(jī)子上面運(yùn)行和在64位機(jī)子上面運(yùn)行占用的內(nèi)存是完全不同的。64位機(jī)子內(nèi)存使用可能是32位機(jī)子的1.5倍。

而壓縮對(duì)象指針,就是指把64位的指針壓縮到32位。

怎么壓縮呢?64位機(jī)子的對(duì)象地址仍然是64位的。壓縮過(guò)的32位存的只是相對(duì)于heap base address的位移。

我們使用64位的heap base地址+ 32位的地址位移量,就得到了實(shí)際的64位heap地址。

對(duì)象指針壓縮在Java SE 6u23 默認(rèn)開(kāi)啟。在此之前,可以使用-XX:+UseCompressedOops來(lái)開(kāi)啟。

數(shù)組對(duì)象頭

java中有一個(gè)非常特別的對(duì)象叫做數(shù)組,數(shù)組的對(duì)象頭和Object有什么區(qū)別嗎?

我們用JOL再看一次:

log.info("{}",ClassLayout.parseClass(byte[].class).toPrintable());

log.info("{}",ClassLayout.parseInstance("www.flydean.com".getBytes()).toPrintable());

上面的例子中我們分別解析了byte數(shù)組的class和byte數(shù)組的實(shí)例:

10:27:32.396 [main] INFO com.flydean.JolUsage - [B object internals:

 OFFSET  SIZE   TYPE DESCRIPTION                               VALUE

      0    16        (object header)                           N/A

     16     0   byte [B.<elements>                             N/A

Instance size: 16 bytes

Space losses: 0 bytes internal + 0 bytes external = 0 bytes total

10:27:32.404 [main] INFO com.flydean.JolUsage - [B 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)                           22 13 07 00 (00100010 00010011 00000111 00000000) (463650)

     12     4        (object header)                           0f 00 00 00 (00001111 00000000 00000000 00000000) (15)

     16    15   byte [B.<elements>                             N/A

     31     1        (loss due to the next object alignment)

Instance size: 32 bytes

Space losses: 0 bytes internal + 1 bytes external = 1 bytes total

看到區(qū)別了嗎?我們發(fā)現(xiàn)數(shù)組的對(duì)象頭是16字節(jié),比普通對(duì)象的對(duì)象頭多出了4個(gè)字節(jié)。這4個(gè)字節(jié)就是數(shù)組的長(zhǎng)度。

整個(gè)對(duì)象的結(jié)構(gòu)

好了,寫(xiě)到這里我們來(lái)總結(jié)一下,java對(duì)象的結(jié)構(gòu)可以分為普通java對(duì)象和數(shù)組對(duì)象兩種:

數(shù)組對(duì)象在對(duì)象頭中多了一個(gè)4字節(jié)的長(zhǎng)度字段。

大家看到最后的字節(jié)是padding填充字節(jié),為什么要填充呢?

因?yàn)镴VM是以8字節(jié)為單位進(jìn)行對(duì)其的,如果不是8字節(jié)的整數(shù)倍,則需要補(bǔ)全。

以上就是淺談java object對(duì)象在heap中的結(jié)構(gòu)的詳細(xì)內(nèi)容,更多關(guān)于java object對(duì)象在heap中的結(jié)構(gòu)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 關(guān)于List、Map、Stream初始化方式

    關(guān)于List、Map、Stream初始化方式

    這篇文章主要介紹了關(guān)于List、Map、Stream初始化方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • Java字節(jié)緩沖流原理與用法詳解

    Java字節(jié)緩沖流原理與用法詳解

    這篇文章主要介紹了Java字節(jié)緩沖流原理與用法,結(jié)合實(shí)例形式總結(jié)分析了java字節(jié)流與緩沖區(qū)相關(guān)原理與操作技巧,需要的朋友可以參考下
    2019-09-09
  • SpringBoot中@ConfigurationProperties 配置綁定

    SpringBoot中@ConfigurationProperties 配置綁定

    本文主要介紹了SpringBoot中@ConfigurationProperties 配置綁定,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • Java中ArrayList的使用詳細(xì)介紹

    Java中ArrayList的使用詳細(xì)介紹

    這篇文章主要介紹了Java中ArrayList的使用,本文給大家詳細(xì)講述該相關(guān)的知識(shí)點(diǎn),并且會(huì)通過(guò)大量的案例加以說(shuō)明,需要的朋友可以參考一下
    2022-04-04
  • SpringBoot應(yīng)用能直接運(yùn)行java -jar的原因分析

    SpringBoot應(yīng)用能直接運(yùn)行java -jar的原因分析

    這篇文章主要介紹了SpringBoot應(yīng)用為什么能直接運(yùn)行java -jar,首先明確一點(diǎn),普通jar包是不能直接運(yùn)行的,比如工具類jar,要能運(yùn)行,至少得要一個(gè)main函數(shù)作為入口吧?本文給大家介紹了詳細(xì)的原因分析,需要的朋友可以參考下
    2024-03-03
  • Java由淺入深通關(guān)抽象類與接口上

    Java由淺入深通關(guān)抽象類與接口上

    在類中沒(méi)有包含足夠的信息來(lái)描繪一個(gè)具體的對(duì)象,這樣的類稱為抽象類,接口是Java中最重要的概念之一,它可以被理解為一種特殊的類,不同的是接口的成員沒(méi)有執(zhí)行體,是由全局常量和公共的抽象方法所組成,本文給大家介紹Java抽象類和接口,感興趣的朋友一起看看吧
    2022-04-04
  • java 將字符串追加到文件已有內(nèi)容后面的操作

    java 將字符串追加到文件已有內(nèi)容后面的操作

    這篇文章主要介紹了java 將字符串追加到文件已有內(nèi)容后面的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-08-08
  • mybatis中返回多個(gè)map結(jié)果問(wèn)題

    mybatis中返回多個(gè)map結(jié)果問(wèn)題

    這篇文章主要介紹了mybatis中返回多個(gè)map結(jié)果問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • Spring5.2.x 源碼本地環(huán)境搭建的方法步驟

    Spring5.2.x 源碼本地環(huán)境搭建的方法步驟

    這篇文章主要介紹了Spring5.2.x 源碼本地環(huán)境搭建的方法步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-09-09
  • springboot+maven快速構(gòu)建項(xiàng)目的示例代碼

    springboot+maven快速構(gòu)建項(xiàng)目的示例代碼

    本篇文章主要介紹了springboot+maven快速構(gòu)建項(xiàng)目的示例代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-08-08

最新評(píng)論

贡山| 昌图县| 云阳县| 涡阳县| 海口市| 稷山县| 东宁县| 海阳市| 定边县| 松原市| 即墨市| 五指山市| 青海省| 大安市| 依兰县| 阿鲁科尔沁旗| 札达县| 南涧| 扶风县| 白沙| 固原市| 石河子市| 门头沟区| 米脂县| 南溪县| 监利县| 泗洪县| 康保县| 黎平县| 铜鼓县| 建德市| 民丰县| 马山县| 松江区| 天等县| 休宁县| 海晏县| 东丰县| 周至县| 获嘉县| 丹阳市|