JDK 27运行时更新详解:G1默认GC、紧凑对象头、JFR脱敏三大变更

JDK 27运行时更新详解:G1默认GC、紧凑对象头、JFR脱敏三大变更

💡 原文中文,约4800字,阅读约需12分钟。
📝

内容提要

JDK 27 将 G1 设为所有环境的默认垃圾回收器,小容器不再自动使用 Serial GC;紧凑对象头默认启用,对象头由 12 字节降至 8 字节以节省内存;JFR 默认对密码、令牌等敏感信息脱敏;移除 JVMCI,影响 Graal 相关项目;jcmd 新增安全属性查询;删除多个旧参数;G1 堆伸缩默认关闭;JSON 线程转储字段改为数字。

🔎

延伸解读

小容器升级需警惕GC默认变更

JDK 27将G1设为所有环境的默认垃圾回收器,包括1核1.7GB的小容器。此前这些环境会自动使用Serial GC,升级后若未显式配置,GC行为将改变。对于吞吐量敏感的后台任务,Serial GC可能更划算。建议升级前测试GC性能,必要时通过-XX:+UseSerialGC显式指定。

紧凑对象头默认启用,内存节省显著

JDK 27默认启用紧凑对象头,对象头从12字节降至8字节,节省约33%的对象头开销。基准测试显示堆使用减少22%,CPU时间减少8%,GC次数减少15%。该特性在JDK 25已可用但需手动开启,现默认生效。除非遇到兼容性问题,否则无需关闭。

JFR默认脱敏,防止敏感信息泄露

JDK 27的JFR默认对密码、API密钥、令牌等敏感信息脱敏,录音文件中显示为[REDACTED]。脱敏发生在数据离开JVM之前,即使录音文件被截获,敏感信息也不会泄露。用户可通过-XX:FlightRecorderOptions自定义过滤规则,或使用none关闭默认过滤。

移除JVMCI与旧参数,升级前需检查

JDK 27移除了JVMCI及相关模块,依赖Graal JIT的项目需调整。同时删除了-noclassgc、-noverify等四个旧参数,升级后使用会报错。-XX:InitiatingHeapOccupancyPercent更名为-XX:G1IHOP,旧名已废弃。建议检查启动脚本和部署配置,及时更新参数。

Q&A

JDK 27 中默认垃圾回收器有什么变化?小容器还会自动用 Serial GC 吗?

JDK 27 将 G1 设为所有环境的默认垃圾回收器,不再根据 CPU 核数或内存大小自动选择 Serial GC。即使容器只有 1 核 CPU、1.7GB 内存,默认也是 G1。Serial GC 仍可手动通过 -XX:+UseSerialGC 启用。

紧凑对象头在 JDK 27 中默认启用后,能节省多少内存?

紧凑对象头将对象头从 12 字节(96 比特)压缩到 8 字节(64 比特),节省约 33%。基准测试显示可减少 22% 堆空间、8% CPU 时间,GC 次数减少 15%,高并行 JSON 解析器快 10%。Amazon 生产环境最高观察到 CPU 用量降低 30%。

JFR 在 JDK 27 中如何保护敏感信息?可以自定义脱敏规则吗?

JFR 默认对密码、API 密钥、令牌等敏感信息脱敏,匹配值显示为 [REDACTED]。脱敏发生在数据离开 JVM 进程之前。可通过 -XX:FlightRecorderOptions:redact-key=dburl 添加自定义过滤,或使用 redact-arguments=@args.txt 引用过滤器文件,在过滤器前加 + 可追加规则,用 none 彻底关闭默认过滤。

JDK 27 移除了 JVMCI,对 GraalVM 或相关项目有什么影响?

JVMCI 相关代码、模块和编译标志(如 -XX:+UseGraalJIT)全部移除,依赖 JVMCI 的项目如 TornadoVM 旧版本无法运行。TornadoVM 6.0 已改用反射、ASM 和 Unsafe 来兼容 JDK 21 到 27。普通开发者影响极小,但需关注 GraalVM 转向月度发布。

JDK 27 中 jcmd 工具有哪些新增功能?

jcmd 新增 VM.security_properties 命令,可打印当前 JVM 进程的 Java 安全属性集合,输出格式脚本友好。VM.info 和致命错误日志现在会报告打开的文件描述符数量。还增加了 Bash 自动补全脚本,可通过 source 加载或放入 /usr/share/bash-completion/completions/ 目录全局生效。

JDK 27 删除了哪些旧的 JVM 启动参数?升级时需要注意什么?

删除了 -noclassgc、-noverify、-verifyremote 和 -Xverify:none。其中 -noclassgc 被 -Xnoclassgc 替代,-verifyremote 被 -Xverify:remote 替代,-noverify 和 -Xverify:none 无替代。使用这些旧参数的启动脚本在 JDK 27 上会报错,需检查 Dockerfile、Kubernetes 配置等。

JDK 27 中 G1 的堆伸缩默认行为有什么变化?对 System.gc() 有什么影响?

G1 的 -XX:MinHeapFreeRatio 默认变为 40 和 70,-XX:MaxHeapFreeRatio 变为 0 和 100,实际上禁用了堆伸缩。Full GC 后不再自动扩缩容,频繁调用 System.gc() 的副作用减少。若显式设置过这两个参数,行为不变。

JDK 27 中 JSON 线程转储格式有什么变化?解析器需要如何调整?

JSON 线程转储中线程 ID、线程数量和进程 ID 从字符串改为数字,例如 { "tid": "3" } 变为 { "tid": 3 }。新增 formatVersion 字段,当前值为 2。解析器若假设这些字段是字符串,升级后会出错,需要改为数字类型。

🏷️

标签

➡️

继续阅读