jol工具可精确打印java对象内存布局,包括对象头、字段偏移、对齐填充等细节;需引入jol-core 0.17依赖,配合classlayout.parseinstance(obj).toprintable()调用,并注意jvm参数(如-xx:+usecompressedoops)对布局的影响。

Java 中不能直接“打印对象的内存结构”——JVM 不暴露真实物理地址,但可以通过专业工具获取对象在堆中的布局细节,包括对象头、字段偏移、对齐填充等。这比简单调用 toString() 深入得多,适用于性能调优、内存分析和底层理解。
用 JOL(Java Object Layout)看真实内存布局
JOL 是 Oracle 官方推荐的权威工具,能精确显示运行时对象的内存分布,不受 JIT 优化干扰。
- 添加 Maven 依赖:
org.openjdk.jol:jol-core:0.17(支持 JDK 8–21) - 写一段测试代码:
public class Person { private byte age; private long id; private boolean active; }Person p = new Person(); System.out.println(ClassLayout.parseInstance(p).toPrintable());
- 输出示例(64 位 + 压缩指针):
OFFSET SIZE TYPE DESCRIPTION VALUE 0 4 (object header) 01 00 00 00 4 4 (object header) 00 00 00 00 8 4 (object header) 90 1c 00 f8 12 4 (loss due to the next object alignment) 16 8 long Person.id 0 24 1 boolean Person.active false 25 1 byte Person.age 0 26 6 (loss due to the next object alignment)可见:字段被 JVM 重排(long优先),age和active合并紧凑存储,末尾有 6 字节填充以满足 8 字节对齐。
区分 Shallow Size 和字段实际占用
关注 Shallow Size(对象自身内存)即可,它 = 对象头 + 所有实例字段大小 + 对齐填充。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 基本类型字段不引用其他对象,所以 Retained Size 和 Shallow Size 相同
- 字段顺序影响大小:把
long/double放前面,int/short居中,byte/boolean放最后,可显著减少填充字节 - JOL 输出里的
OFFSET列是验证字段是否被重排的唯一依据
配合 JVM 参数看清压缩指针影响
是否启用压缩指针(-XX:+UseCompressedOops)会改变对象头和引用字段大小:
- 默认开启时:Klass Pointer 占 4 字节(对象头共 12 字节)
- 关闭后(
-XX:-UseCompressedOops):Klass Pointer 升为 8 字节(对象头共 16 字节) - 运行 JOL 时加上对应 JVM 参数,才能得到与生产环境一致的布局结果
不建议用 hashCode 或 identityHashCode 当内存地址
它们返回的是哈希值,不是真实地址:
-
obj.hashCode()可能被重写,且默认实现也不等于地址 -
System.identityHashCode(obj)虽稳定,但仍是哈希码,仅在未重写且未锁膨胀时接近地址值 -
sun.misc.Unsafe获取地址属内部 API,JDK 9+ 已强限制,不可用于生产
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










