java中string对象内存占用可用jol工具精确分析,包括对象头、字段、数组引用及对齐填充;jdk9+默认启用compact strings(byte[]存储),影响实际大小,需结合vm参数和new实例避免常量池干扰。

Java 中 String 对象的内存占用可以用 JOL(Java Object Layout)工具直观查看,它能精确展示对象在 JVM 中的实际布局,包括对象头、字段、对齐填充等细节。
安装并引入 JOL 依赖
JOL 是 OpenJDK 提供的开源工具,推荐使用 Maven 引入:
- Maven 依赖(最新版参考 GitHub 官方仓库):
确保项目能正常编译运行后,即可调用 JOL API 分析对象。
查看 String 对象内存布局的代码示例
以 JDK 8 或 JDK 11+(未开启 Compact Strings 时)为例,String 内部字段为 char[] value,而 JDK 9+ 默认启用 Compact Strings(使用 byte[] value + coder),影响实际大小:
- 基础分析代码:
import org.openjdk.jol.vm.VM;
public class StringSizeDemo {
public static void main(String[] args) {
String s = "hello";
System.out.println(VM.current().details()); // 查看 JVM 参数(如是否启用 Compact Strings)
System.out.println(GraphLayout.parseInstance(s).toPrintable());
}
}
输出中会显示:
- 对象头大小(通常 12 字节:Mark Word 8 + Class Pointer 4,在 64 位开启压缩指针时)
- String 类自身字段(如 value、offset、count、hash 等 —— 注意:JDK 9+ 已移除 offset/count,仅保留 value、coder、hash)
- 引用字段指向的 char[] 或 byte[] 数组对象(单独计算其大小)
- 对齐填充(保证对象总大小为 8 字节倍数)
区分 JDK 版本对 String 内存的影响
JDK 9 起默认启用 Compact Strings(-XX:+UseCompactStrings),String 使用 byte[] 存储字符(ASCII 用 1 字节/字符),否则回退到 char[](2 字节/字符):
- 验证是否启用:运行
VM.current().details(),搜索UseCompactStrings - 强制关闭 Compact Strings(用于对比):
-XX:-UseCompactStrings - 例如 "hello"(5 个 ASCII 字符):
✔ 启用 Compact Strings →byte[5]占用 24 字节(数组对象头 12 + data 5 + padding 7)
✔ 关闭后 →char[5]占用 32 字节(数组对象头 12 + data 10 + padding 10)
注意 String 的不可变性与字符串常量池影响
JOL 查看的是堆中具体对象实例,但需注意:
- 字面量如
"hello"通常位于字符串常量池(堆中),重复声明不会新建对象,JOL 显示的是同一个实例 - 通过
new String("hello")会额外创建一个堆上 String 对象(且其value可能复用常量池中已有的数组) - 若想分析“全新”对象,建议用
new String(new char[]{'h','e','l','l','o'})避免共享数组
不复杂但容易忽略。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











