0
点赞
收藏
分享

微信扫一扫

JVM 对象内存布局

什么是 JVM 对象内存布局?

JVM 对象内存布局 描述了 Java 对象在堆内存中的存储结构,主要包括以下几个部分:

组成部分

描述

对象头(Object Header)

存储哈希码、GC 分代年龄、锁状态标志、线程持有锁等信息

实例数据(Instance Data)

对象中定义的字段变量(如 int ageString name

对齐填充(Padding)

为了满足 JVM 内存对齐要求而填充的无意义字节

步骤一:添加 JOL 依赖(Maven)

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

步骤二:查看一个空对象的内存布局

import org.openjdk.jol.vm.VM;
import org.openjdk.jol.info.ClassLayout;

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

📌 输出示例(64 位 JVM,未开启压缩指针):

java.lang.Object object internals:
OFFSET  SIZE   TYPE DESCRIPTION                               VALUE
      0     4        (object header)                           01 00 00 00 (00000001 00000000 00000000 00000000)
      4     4        (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000)
      8     4        (object header)                           e5 07 00 00 (11100101 00000111 00000000 00000000)
     12     4        (loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 4 bytes internal + 4 bytes external = 8 bytes total

 说明:一个空对象竟然占用了 16 字节

步骤三:查看一个包含字段的对象布局

public class User {
    boolean flag;
    int age;
    String name;
}

public class FieldObject {
    public static void main(String[] args) {
        User user = new User();
        System.out.println(ClassLayout.parseInstance(user).toPrintable());
    }
}

输出示例:

com.example.User object internals:
OFFSET  SIZE      TYPE DESCRIPTION                               VALUE
      0     4           (object header)                           ...
      4     4           (object header)                           ...
      8     4           (object header)                           ...
     12     4   boolean User.flag                                 false
     16     4       int User.age                                  0
     20     4  java.lang.String User.name                         null
     24     0           (loss due to the next object alignment)
Instance size: 24 bytes

 说明:字段在对象中是按类型大小对齐存储的,且顺序会影响内存占用。

步骤四:实战分析字段顺序优化

public class A {
    byte b1;
    int i1;
    byte b2;
}

public class B {
    byte b1;
    byte b2;
    int i1;
}

分析:

  • 类 A:b1 (1) + padding (3) + i1 (4) + b2 (1) + padding (3) → 12 bytes
  • 类 B:b1 (1) + b2 (1) + padding (2) + i1 (4) → 8 bytes

 通过调整字段顺序,可以节省 4 字节内存

举报

相关推荐

0 条评论