欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

對象和其隱藏的秘密

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

接下來我們來對這個java對象的鼻祖進行一個詳細(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());
    }
}

代碼很簡單,我們打印JVM的信息,Object class和一個新的Object實例的信息。

看下輸出:

[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中,一個Object實例是占用16個字節(jié)。

因為Object對象中并沒有其他對象的引用,所以我們看到Object對象只有一個12字節(jié)的對象頭。剩下的4個字節(jié)是填充位。

Object對象頭

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

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

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

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

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

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

第二部分就是Klass Word,Klass Word是一個類型指針,指向class的元數(shù)據(jù),JVM通過Klass Word來判斷該對象是哪個class的實例。

且慢!

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

沒錯,如果沒有開啟COOPs就是128bits,如果開啟了COOPs,那么Klass Word的大小就從64bits降到了32bits。

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

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

對象指針用來指向一個對象,表示對該對象的引用。通常來說在64位機子上面,一個指針占用64位,也就是8個字節(jié)。而在32位機子上面,一個指針占用32位,也就是4個字節(jié)。

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

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

怎么壓縮呢?64位機子的對象地址仍然是64位的。壓縮過的32位存的只是相對于heap base address的位移。

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

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

數(shù)組對象頭

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

我們用JOL再看一次:

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

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

上面的例子中我們分別解析了byte數(shù)組的class和byte數(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ù)組的對象頭是16字節(jié),比普通對象的對象頭多出了4個字節(jié)。這4個字節(jié)就是數(shù)組的長度。

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

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

數(shù)組對象在對象頭中多了一個4字節(jié)的長度字段。

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

因為JVM是以8字節(jié)為單位進行對其的,如果不是8字節(jié)的整數(shù)倍,則需要補全。

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

相關(guān)文章

  • 一文簡單了解C#?中的DataSet類

    一文簡單了解C#?中的DataSet類

    這篇文章主要介紹了一文簡單了解C#?中的DataSet類,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-08-08
  • EditPlus運行java時從鍵盤輸入數(shù)據(jù)的操作方法

    EditPlus運行java時從鍵盤輸入數(shù)據(jù)的操作方法

    這篇文章主要介紹了EditPlus運行java時從鍵盤輸入數(shù)據(jù)的操作方法,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-03-03
  • Java中 this和super的用法與區(qū)別小結(jié)

    Java中 this和super的用法與區(qū)別小結(jié)

    在Java的學(xué)習(xí)與開發(fā)者我們經(jīng)常遇到this和super關(guān)鍵字,本文主要介紹了Java中 this和super的用法與區(qū)別小結(jié),具有一定的參考價值,感興趣的可以了解一下
    2023-12-12
  • 關(guān)于spring依賴注入的方式以及優(yōu)缺點

    關(guān)于spring依賴注入的方式以及優(yōu)缺點

    這篇文章主要介紹了關(guān)于spring依賴注入的方式以及優(yōu)缺點,依賴注入,是IOC的一個方面,是個通常的概念,它有多種解釋,這概念是說你不用創(chuàng)建對象,而只需要描述它如何被創(chuàng)建,需要的朋友可以參考下
    2023-07-07
  • Java基礎(chǔ)知識之ByteArrayOutputStream流的使用

    Java基礎(chǔ)知識之ByteArrayOutputStream流的使用

    這篇文章主要介紹了Java基礎(chǔ)知識之ByteArrayOutputStream流的使用,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • mybatis注解之@Mapper和@MapperScan的使用

    mybatis注解之@Mapper和@MapperScan的使用

    這篇文章主要介紹了mybatis注解之@Mapper和@MapperScan的使用,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • QueryWrapper中or的使用技巧分享

    QueryWrapper中or的使用技巧分享

    在日常的開發(fā)工作中,處理數(shù)據(jù)庫查詢是一個非常常見的任務(wù),尤其是當(dāng)我們需要在復(fù)雜條件下篩選數(shù)據(jù)時,如何編寫高效、簡潔且可維護的查詢邏輯顯得尤為重要,本文給大家介紹了QueryWrapper中or的使用技巧,需要的朋友可以參考下
    2024-10-10
  • SpringBoot壓縮json并寫入Redis的示例代碼

    SpringBoot壓縮json并寫入Redis的示例代碼

    由于業(yè)務(wù)需要,存入redis中的緩存數(shù)據(jù)過大,占用了10+G的內(nèi)存,內(nèi)存作為重要資源,需要優(yōu)化一下大對象緩存,所以我們需要對json進行壓縮,本文給大家介紹了SpringBoot如何壓縮Json并寫入redis,需要的朋友可以參考下
    2024-08-08
  • SpringMVC實現(xiàn)文件上傳與下載、攔截器、異常處理器等功能

    SpringMVC實現(xiàn)文件上傳與下載、攔截器、異常處理器等功能

    這篇文章主要給大家介紹了關(guān)于SpringMVC實現(xiàn)文件上傳與下載、攔截器、異常處理器等功能的相關(guān)資料,這些功能在我們?nèi)粘i_發(fā)中經(jīng)常會遇到,本文通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2021-09-09
  • Java實現(xiàn)給微信群中定時推送消息

    Java實現(xiàn)給微信群中定時推送消息

    這篇文章主要為大家詳細(xì)介紹了Java如何實現(xiàn)給微信群中定時推送消息的功能,文中的示例代碼講解詳細(xì),具有一定的借鑒價值,需要的可以了解一下
    2022-12-12

最新評論