Java对象内存布局和对象头

对象布局

对象的存储布局

一个对象在堆内存中的存储布局是由三部分来组成的:

  • 对象头
  • 实例数据
  • 对齐填充(保证8个字节的倍数)
    Image

对象头结构

java对象的对象头由两部分构成:

  • 对象标记(又称为Mark Word)
  • 类元信息(又称为类型指针)
Mark Word的作用

默认存储对象的HashCode、分代年龄和锁标志位等信息。
这些信息都是与对象自身定义无关的数据,所以MarkWord被设计成一个非固定的数据结构以便在极小的空间内存存储尽量多的数据。
它会根据对象的状态复用自己的存储空间,也就是说在运行期间MarkWord里存储的数据会随着锁标志位的变化而变化。
mark word
他的存储内容是什么

存储内容标志位状态
对象哈希码,对象分代年龄01未锁定
指向锁记录的指针00轻量级锁定
指向重量级锁的指针10膨胀(重量级锁定)
空,不需要记录信息11GC标记
偏向线程ID,偏向时间戳,对象分带年龄01可偏向

在64位系统中,Mark Word占了8个字节(就是64bit大小的存储容量),其具体的存储结构为:
mark word具体占用的内存空间作用

小知识点:GC年龄采用4位bit存储,最大也只能为15,所以MaxTenuringThreshold参数默认值就是15,也不能超过15

类型指针

直接指向了方法区内的kclass信息

对象头的大小

在64位系统中,Mark Word占用了8个字节,类型指针占用了8个字节,对象头总计是16个字节的大小

实例数据

存放类的属性(Field)数据信息,包括父类的属性信息,如果是数组的实例部分还包括数组的长度,这部分内存按4字节对齐。

对齐填充

虚拟机要求对象起始地址必须是8字节的整数倍。填充数据不是必须存在的,仅仅是为了字节对齐,这部分内存按8字节补充对齐。

代码证明
引入JOL依赖

用来分析Java虚拟机和对象的一些基础信息

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

Java代码证明

static class MyObject {
        int i =89;
        long a = 889;
        char b = 'b';
    }

    public static void main(String[] args) {
        System.out.println(ClassLayout.parseInstance(new MyObject()).toPrintable());
    }

压缩指针介绍

尾巴参数说明

java -XX:+PrintCommandLineFlags -version 这个可以显示JVM自带的的一些默认参数出来
64位的JVM自己默认就开启了压缩指针 默认是这个参数 -XX:+UseCompressedClassPointers

开启压缩与不开启的区别

开启压缩时,类型指针就为4个字节,不开启的时候类型指针为8个字节

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

life or die

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值