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

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

 更新時間:2022年05月05日 15:32:27   作者:舊時明月丶  
這篇文章主要介紹了Java對象的內(nèi)存布局全流程,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

開始先拋出一個問題:一個對象o,Object o = new Object();創(chuàng)建完成后會占用多少字節(jié)的內(nèi)存?

要能回答這個問題,就需要了解java對象的內(nèi)存布局。

對象內(nèi)存布局

一個Java對象在內(nèi)存中包括對象頭、實例數(shù)據(jù)和對齊填充三個部分。如下圖所示:

在這里插入圖片描述

對象頭

  • Mark Word:包含一系列的標記位比如hashcode、GC分代年齡、偏向鎖位,鎖標志位等。這個Mark Word在對象被加了不同量級的鎖時所包含的內(nèi)容和布局都有所不同,這涉及到鎖升級的知識,暫不展開討論
  • Klass Pointer:是一個指針,指向描述這個對象類型的元對象,例如Object.class,User.class等

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

  • instance data:描述成員變量的信息,如果成員變量是引用類型,那么它就是一個指針。instance data的大小是所有成員變量的占用空間(基本數(shù)據(jù)類型大小+指針大?。?/li>

對齊

  • padding:在java中,為了能夠更加高效的利用內(nèi)存空間,會將對象大小設定為8bytes的整數(shù)倍,如果對象頭+實例數(shù)據(jù)的大小不是8bytes的倍數(shù),那么會在padding區(qū)域填充幾個字節(jié),使得對象占用空間是8bytes的倍數(shù)

那么對象布局中各個部分占用內(nèi)存空間到底多大呢?

對象占用內(nèi)存空間

由于目前64位操作系統(tǒng)已經(jīng)基本普及,下面只分析64位操作系統(tǒng)下的情況

指針壓縮

在64位系統(tǒng)中,一個指針占64 bits也就是8 bytes,而在32位系統(tǒng)中指針只占4個字節(jié),于是為了能夠減少內(nèi)存消耗,從JDK1.6開始,JVM會默認支持指針壓縮,會將指針大小壓縮成4個字節(jié),

這涉及到兩個參數(shù)-XX:+UseCompressedOops,-XX:+UseCompressedClassPointers。

  • UseCompressedOops:oops: ordinary object pointer,普通對象指針壓縮,例如Object o = new Object();其中o就是個指向new Object()對象的指針,o在指針壓縮前占用8個字節(jié),在指針壓縮后占用4個字節(jié)
  • UseCompressedClassPointers:壓縮Klass Pointer,壓縮前8個字節(jié),壓縮后4個字節(jié)

對象頭

Mark Word占8個字節(jié)

  • Klass Pointer:開啟(默認)壓縮4個字節(jié),不開啟壓縮8個字節(jié)

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

  • instance data:根據(jù)實際情況計算:如果成員變量是基本數(shù)據(jù)類型,那么占用空間就是基本數(shù)據(jù)類型的大小,Java的8大基本數(shù)據(jù)類型的大小如下:
數(shù)據(jù)類型占用空間bytes
byte1
short2
int4
long8
float4
double8
char2
boolean1

如果成員變量是引用類型,那么就是一個指針大?。ㄩ_啟指針壓縮占4字節(jié),不開啟指針壓縮8字節(jié))

對齊

  • padding:如果對象頭+實例數(shù)據(jù)的大小不是8 bytes的倍數(shù),那么就填充這個區(qū)域,使得對象占用空間能被8個字節(jié)整除(最小情況)

口說無憑,下面將會通過實驗證明

證明對象內(nèi)存布局

我們需要引用一個依賴:openjdk提供的jol-core:

<dependency>
	<groupId>org.openjdk.jol</groupId>
	<artifactId>jol-core</artifactId>
	<version>0.9</version>
</dependency>

1.查看默認情況下沒有成員變量的對象布局

示例代碼:

public class TestObj {
    public static void main(String[] args) {
        // 創(chuàng)建對象
        Object o = new Object();
        // 獲得對象布局內(nèi)容
        String s = ClassLayout.parseInstance(o).toPrintable();
        // 打印對象布局
        System.out.println(s);
    }
}

輸出結(jié)果:

在這里插入圖片描述

其中對象頭(object header)有三個,前兩個是Mark Word一共8個字節(jié),后面一個是Klass Pointer,占4個字節(jié),由于沒有成員變量,所以實例數(shù)據(jù)沒有占用空間,而最后4個字節(jié)描述信息為:loss due to the next object alignment,意思就是為了與下一個對象對齊而丟失的部分,也就是對齊填充空間

2.證明Klass Pointer在不開啟壓縮的情況下占用8個字節(jié)

我們只需要在jvm參數(shù)上加上-XX:-UseCompressedClassPointers即可,在IDEA工具中可以設置啟動參數(shù):

在這里插入圖片描述

還是運行上述代碼,運行程序結(jié)果:

在這里插入圖片描述

如上圖所示,對象頭已經(jīng)占用16個字節(jié),前8個字節(jié)是Mark Word,后8個字節(jié)就是未壓縮的Klass Pointer。我們還注意到對齊填充也沒有了,原因是此時對象占用空間16個字節(jié)已經(jīng)是8bytes的倍數(shù),所以不需要填充,這完全印證了前面的分析

3.證明實例數(shù)據(jù)的存在以及大小

示例代碼:

public class TestObj {
    public static void main(String[] args) {
        // 創(chuàng)建對象
        User user = new User(1, "zhangsan");
        // 獲得對象布局內(nèi)容
        String s = ClassLayout.parseInstance(user).toPrintable();
        // 打印對象布局
        System.out.println(s);
    }
}
class User {
    private int id;
    private String name;
    public User(int id, String name) {
        this.id = id;
        this.name = name;
    }
}

打印結(jié)果:

在這里插入圖片描述

如上圖所示,int類型的id占用4個字節(jié),指向字符串對象的name指針占用4個字節(jié),加上對齊,對象一共占用24 bytes

4.最后驗證不開啟指針壓縮的情況下指針占用8 bytes

只需在jvm參數(shù)上加上-XX:-UseCompressedOops:

在這里插入圖片描述

還是運行上面的代碼,打印結(jié)果:

在這里插入圖片描述

很顯然,此時name指針已經(jīng)占用了8個字節(jié)

一般來說,UseCompressedClassPointers和UseCompressedOops是默認開啟的,我們無需關心也無需修改。但是有個隱藏的細節(jié)就是:UseCompressedClassPointers的開啟依賴UseCompressedOops的開啟,并且開啟UseCompressedOops 也默認強制開啟UseCompressedClassPointers,關閉UseCompressedOops 默認關閉UseCompressedClassPointers。

至此,關于java對象的內(nèi)存布局已經(jīng)有了一個基本的了解,那么文章一開始的問題現(xiàn)在應該能很輕松的回答:16個字節(jié)。

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關文章

  • logback如何去掉DubboMonitor煩人的INFO日志

    logback如何去掉DubboMonitor煩人的INFO日志

    這篇文章主要介紹了logback如何去掉DubboMonitor煩人的INFO日志方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • jpa實現(xiàn)多對多的屬性時查詢的兩種方法

    jpa實現(xiàn)多對多的屬性時查詢的兩種方法

    這篇文章主要介紹了jpa實現(xiàn)多對多的屬性時查詢的兩種方法,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • Java畢業(yè)設計實戰(zhàn)之線上水果超市商城的實現(xiàn)

    Java畢業(yè)設計實戰(zhàn)之線上水果超市商城的實現(xiàn)

    這是一個使用了java+SSM+springboot+redis開發(fā)的網(wǎng)上水果超市商城,是一個畢業(yè)設計的實戰(zhàn)練習,具有水果超市商城該有的所有功能,感興趣的朋友快來看看吧
    2022-01-01
  • SpringBoot 簽到獎勵實現(xiàn)方案的示例代碼

    SpringBoot 簽到獎勵實現(xiàn)方案的示例代碼

    這篇文章主要介紹了SpringBoot 簽到獎勵實現(xiàn)方案的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-08-08
  • spring配置文件解析失敗報”cvc-elt.1: 找不到元素 ''''beans'''' 的聲明”異常解決

    spring配置文件解析失敗報”cvc-elt.1: 找不到元素 ''''beans'''' 的聲明”異常解決

    這篇文章主要給大家介紹了關于spring配置文件解析失敗報”cvc-elt.1: 找不到元素 'beans' 的聲明”異常的解決方法,需要的朋友可以參考下
    2020-08-08
  • 使用@TransactionalEventListener監(jiān)聽事務教程

    使用@TransactionalEventListener監(jiān)聽事務教程

    這篇文章主要介紹了使用@TransactionalEventListener監(jiān)聽事務教程,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • Java設計模式之橋接模式

    Java設計模式之橋接模式

    這篇文章介紹了Java設計模式之橋接模式,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-09-09
  • 一文搞懂?MyBatis的事務管理機制

    一文搞懂?MyBatis的事務管理機制

    MyBatis是一款優(yōu)秀的持久層框架,相信很多Java后端開發(fā)人員對它都不會陌生。本文將從事務概述、MyBatis實現(xiàn)事務的方式、事務實現(xiàn)源碼分析方面詳細解析MyBatis的事務管理機制,需要的朋友可以參考下
    2023-05-05
  • java偽泛型知識點詳解

    java偽泛型知識點詳解

    在本篇文章里小編給大家整理的是一篇關于java偽泛型知識點詳解內(nèi)容,有需要的朋友們可以跟著學習參考下。
    2021-06-06
  • Eclipse智能提示及快捷鍵

    Eclipse智能提示及快捷鍵

    本文主要介紹了Eclipse智能提示及快捷鍵的相關知識,具有很好的參考價值。下面跟著小編一起來看下吧
    2017-03-03

最新評論

府谷县| 佳木斯市| 同江市| 延长县| 澄江县| 庄河市| 古蔺县| 泾阳县| 陵川县| 北川| 朔州市| 黄冈市| 扶沟县| 丰镇市| 连山| 阿巴嘎旗| 油尖旺区| 沂源县| 长春市| 平阴县| 当阳市| 运城市| 长泰县| 密山市| 尼木县| 马山县| 鄢陵县| 修武县| 石柱| 乐山市| 云浮市| 海阳市| 彩票| 神池县| 辰溪县| 全南县| 商都县| 绥化市| 花莲县| 郁南县| 纳雍县|