Java对象的内存结构

HotSpot虚拟机中,对象在内存中存储的布局可以分为三块区域:

  • 对象头(Header)
  • 示例数据(Instance Data)
  • 对其填充(Padding)

在这里插入图片描述

Mark Word(标记字段)

其内容是一系列的标记位,用于储存对象自身运行时的数据,如HashCode、GC分代年龄、锁状态标志、线程持有锁、偏向线程ID、偏向时间戳等

占用内存为一个机器码,32为系统占用4个字节,64位系统位8个字节。

以32位系统为例:在无锁状态下包含,25Bit对象的hashcode、4bit 对象的分代年龄、1bit 是否是偏向锁、2bit 锁标志位
在这里插入图片描述
考虑到虚拟机的空间效率,Mark Word被设计成一个非固定的数据结构以便于在极小空间内存存储尽量多的数据,他会根据对象的状态复用自己储存空间,也就是说,Mark Word会随着程序的运行发生变化。

Klass Pointer(类型指针)

类型指针指向对象的类元数据的内存地址、虚拟机通过这和指针确定该对象是哪个类的实例占用内存为一个机器码,32位系统一个机器码为4个字节,64位系统一个机器码为 8字节一个对象头一般占用两个机器码,但是数组稍微特殊,使用三个机器码,其中一个机器码用来存放数组长度。

对象的实例数据

这里面包含了对象的所有成员变量,其大小由各个成员变量的大小决定,比如:

  • byte和boolean是一个字节
  • short和char是2个字节
  • int 和 float 是4个字节
  • long和double是8个字节
  • 引用类型在32位系统上每个占用4字节,在64位系统上每个占8字节

对齐填充

HotSpot VM 的自动内存管理系统要求对象起始地址必须是8字节的整数倍。

在64位系统下:

  • new int[0]:对象头(8 + 24字节)+实例数据(0字节)+对齐填充(0字节)= 32 字节;
  • new int[1]:对象头(8 + 24字节)+ 实例数据 (基本类型 4 字节) + 对齐填充 (4字节) =40字节
  • integer a :对象头(8+ 16字节)+ 示例数据 (引用类型 8 字节) + 对齐填充 (0字节) = 32字节

对象头中:
标记字段位8字节
然后是类型指针字段 数组占用三个机器码 24 其他占用两个子起码位16字节


版权声明:本文为qq_45795744原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。