Java对象内存布局和对象头

Java对象内存布局和对象头

在 HotSpot 虚拟机中,对象在内存中的布局分为三块区域:对象头,实例数据和对齐填充。

对象头中包含两部分:MarkWord 和 类型指针。如果是数组对象的话,对象头还有一部分是存储数组的长度。

多线程下 synchronized 的加锁就是对同一个对象的对象头中的 MarkWord 中的变量进行CAS操作

Java对象内存布局和对象头_第1张图片

  • 对象头(在64位系统中,Mark Word占了8个字节,类型指针占了8个字节,一共是16个字节)

    • 对象标记(Mark Word)
    • Java对象内存布局和对象头_第2张图片
    • 默认存储对象的HashCode、分代年龄和锁标志等信息。
    • 这些信息都是与对象自身定义无关的数据,所以Mark Word被设计成一个非固定的数据结构以便在极小的空间内存存储尽量多的数据。
    • 它会根据对象的状态复用自己的存储空间,也就是说在运行期间MarkWord里存储的数据会随着锁标志位的变化而变化
    • 类元信息(类型指针)
      • 对象指向它的类元数据的指针,虚拟机通过这个指针来确定这个对象哪个类的实例
  • 实例数据

    • 存放类的属性(Field)数据信息,包括父类的属性信息
  • 对齐填充(保证8个字节的倍数)

    • 虚拟机要求对象起始地址必须是8字节的整数倍,填充数据不是必须存在的,仅仅是为了字节对齐,这部分内存按8字节补充对齐。
对象头的长度
长度 内容 说明
32/64bit MarkWord 存储对象的hashCode或锁信息等
32/64bit Class Metadada Address 存储对象类型数据的指针
32/64bit Array Length 数组的长度(如果当前对象是数组)

如果是数组对象的话,虚拟机用3个字宽(32/64bit + 32/64bit + 32/64bit)存储对象头,如果是普通对象的话,虚拟机用2字宽存储对象头(32/64bit + 32/64bit)。

你可能感兴趣的:(JUC,java,开发语言)