Java对象内存布局

对象内存布局

在这里插入图片描述

对象头

对象头包含了两部分,分别是 运行时元数据(Mark Word) 类型指针

如果是数组,还需要记录数组的长度

运行时元数据(Mark Word)
  • 哈希值(HashCode)
  • GC分代年龄
  • 锁状态标志
  • 线程持有的锁
  • 偏向线程ID
  • 翩向时间戳
类型指针

指向类元数据InstanceKlass,确定该对象所属的类型。指向的其实是方法区中存放的类元信息

实例数据(Instance Data)

实例数据部分是对象真正存储的有效信息,也既是我们在程序代码里面所定义的各种类型的字段内容,无论是从父类继承下来的,还是在子类中定义的都需要记录下来。

这部分的存储顺序会受到虚拟机分配策略参数FieldsAllocationStyle和字段在Java源码中定义顺序的影响。HotSpot虚拟机 默认的分配策略为 longs/doubles intsshorts/charsbytes/booleans、oops(Ordinary
Object Pointers),从分配策略中可以看出,相同宽度的字段总是被分配到一起。在满足这个前提条件的情况下,在父类中定义的变量会出现在子类之前。如果 CompactFields参数值为true(默认为true),那子类之中较窄的变量也可能会插入到父类变量的空隙之中。

对其填充(Padding)

对齐填充并不是必然存在的,也没有特别的含义,它仅仅起着占位符的作用。由于HotSpotVM的自动内存管理系统要求对象起始地址必须是8字节的整数倍,换句话说就是对象的大小必须是8字节的整数倍·。对象头正好是8字节的倍数(1倍或者2倍),因此当对象实例数据部分没有对齐的话,就需要通过对齐填充来补全。

总结

在这里插入图片描述

Object obj= new Object() 做了什么操作,申请了哪些内存占用的大小?

  • new Object (); 创建一个User对象,内存分配在堆上
  • Object obj; 创建一个引用,内存分配在栈上
  • = 将Object 对象地址赋值给引用

指针压缩参数设置:

-XX:+UseCompressedOops  开启指针压缩
-XX:-UseCompressedOops  关闭指针压缩
  1. 未开启指针压缩 占用大小为:8(Mark Word)+8(Class Pointer)=16字节

  2. 开启了指针压缩(默认是开启的) 开启指针压缩后,Class Pointer会被压缩为4字节,最终大小为: 8(Mark Word)+4(Class Pointer)+4(对齐填充)=16字节

引入坐标

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

Object的Demo(开启指针压缩)

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

在这里插入图片描述

Object的Demo(关闭指针压缩)
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值