Java 对象内存布局

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

  • 对象头(Header) :包含 markword 标记字段类型指针32 位上大小是 8 个字节64 位 16 个字节
  • 实例数据(Instance Data):包含了对象的所有成员变量,其大小由各个成员变量的大小决定,HotSpot虚拟机的默认分配策略中,宽度相等的字段总是被分配到一起存放,如longdouble, shortcharbyteboolean
  • 对齐填充(Padding) :占位符的作用,HotSpot 虚拟机要求对象的大小必须是 8 字节的整数倍因为对象头部分被精心设计成是 8 字节的倍数(1倍或2倍)),这部分并不是必然存在的,如果对象实例数据没有对齐的话,就需要通过对齐填充进行补全。

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

对象头又包括:

  • markword 标记字段哈希码、GC分代年龄、锁状态等,32位上是4字节,64位8字节
  • 类型指针指向对象的类型元数据的指针JVM 通过这个指针来确定这个对象是属于哪个类的实例32 位 4 字节,64 位开启指针压缩 4 字节,否则 8 字节,jdk 1.8 默认开启指针压缩后为 4 字节
  • 数组长度如果对象是一个数组对象, 那在对象头中还必须有一块数据用于记录数组长度。 4 字节

Java 对象内存布局_第3张图片

对于 64 位上的一个空对象:

Java 对象内存布局_第4张图片

也就是说,在 64 位系统上,不开启指针压缩的情况下,一个空对象也要占用 16 字节的大小,而如果这个对象是数组对象,还要额外占用 4 字节,即 20 字节。

所以,在开发中应当尽量避免使用包装类型和枚举类型作为参数类型设计,使用包装类型除了拆装箱的开销外,在数据规模较大的情况下,还有可能占用较大的内存或者造成内存抖动。

你可能感兴趣的:(Java知识笔记,java,对象内存,对象头,markword,类元指针,对齐填充)