Java对象内存布局

1 Java对象的内存布局

在HotSpot虚拟机里,对象在堆内存的存储布局可以划分为三个部分:对象头(Header)、实例数据(Instance Data)和对齐填充(Padding,保证对象始终为8字节的倍数)。

 1.1 对象头

对象头分为对象标记(markOop)和类元信息(klassOop),类元信息存储的是指向该对象类元数据(klass)的首地址。如果是数组对象的话,对象头还会包含数组长度。

  • MarkWord:记录了对象和锁有关的信息,在64位JVM的大小是64bit。当这个对象被synchronized关键字当成同步锁时,围绕这个锁的一系列操作都和Mark Word有关,下面是64位JVM的MarkWord在不同锁状态下对应的不同内容,最后2bit是锁标记位,用于表示不同的锁状态。
  • klass类元信息:又称类型指针,在64位JVM是64bit(忽略压缩指针的影响)。对象指向它的类元数据(存放在方法区)的指针,虚拟机通过这个指针来确定这个对象是哪个类的实例。
 1.2 实例数据

存放类的属性数据信息,包括父类的属性信息。

 1.3 对齐填充

因为JVM要求java的对象占的内存大小应该是8字节的倍数,所以后面有几个字节用于把对象的大小补齐至8字节的倍数,没有特别的功能。

1.4 JOL代码验证(64位JVM)

引入maven依赖:

        <dependency>
            <groupId>org.openjdk.jol</groupId>
            <artifactId>jol-core</artifactId>
            <version>0.9</version>
        </dependency>
class Customer {
    int id;
    boolean flag = false;
}

测试Customer类:

public class Juc118_Jol {
    public static void main(String[] args) {
        Customer customer = new Customer();
        System.out.println(ClassLayout.parseInstance(customer).toPrintable());
    }
}

打印结果如下:

MarkWord:4字节(0-7)

klass类元指针:8-11,这里类型指针占4字节是由于压缩指针的缘故

实例数据:id 4个字节,flag 1个字节

对齐填充:为了17字节补齐到24字节(8的倍数)的7字节的对齐填充

1.5 压缩指针

java默认开启了压缩指针(-XX:+UseCompressedClassPointers),以节约空间。如果不想要压缩指针,配置如下即可:

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值