欢迎光临
我们一直在努力

JDK27升级后小容器GC和内存默认值变了

升级到 JDK 27 之后,小容器上的 GC 和内存默认值变了什么

JDK 27 已于 2026-09-15 正式 GA。对跑在单核、小内存 Pod 里的 Java 服务来说,这次升级不只是换个版本号:默认 GC 选择规则、紧凑对象头、G1 堆空闲比例默认值都动了。若镜像还按「小容器会自动 Serial」的经验打包,上线后可能看到停顿特征变了、RSS 曲线偏了,甚至和旧 CDS 归档对不上。下面按可复现口径,把变化、原因和检查清单说清楚。

场景痛点:小容器里「默认」不再等于「省事」

常见误区有三类:

  • 认为 ActiveProcessorCount=1 或 -Xmx 很小就会自动 Serial,升级后仍不显式指定 GC。
  • 依赖历史 MinHeapFreeRatio/MaxHeapFreeRatio 默认值让堆「慢慢涨、慢慢缩」,却没意识到 G1 下默认约束已放宽到几乎不缩放。
  • 打开紧凑对象头相关 CDS 镜像时,部署目录仍指向旧 .jsa,启动阶段才发现归档不匹配。
  • 这些都不需要改业务代码,但会改变延迟尾部与内存水位。下面先回答升级时被问得最多的两句。

    未指定 GC 时默认选谁?旧 Serial 条件是什么?

    未指定 GC 时一律 G1;旧 Serial 条件是单 CPU 或物理内存<1792MB。

    JEP 523:默认 GC 选择规则

    JDK 27 之前(含沿用多年的容器启发式),在未显式指定收集器时,若判定为 single CPU,或物理内存 less than 1792 MB,会倾向 Serial;否则倾向 G1。口径就是「单 CPU」与「物理内存 <1792MB」,不是「少于 2 个处理器」这类近似说法。

    自 JDK 27 起(JEP 523):只要未显式指定 GC,一律使用 G1。旧启发式不再挡在默认路径上。若你仍需要 Serial,必须显式打开,且显式开关优先:

    -XX:+UseSerialGC

    可在升级前后用同一组参数对比「选了谁」(只给命令,不贴伪造输出):

    java -XX:ActiveProcessorCount=1 -Xmx512m -Xlog:gc*:stdout -version

    在 JDK 26 及更早版本上,上述组合更容易落到 Serial;在 JDK 27 上,若未加 -XX:+UseSerialGC,日志侧应体现 G1。生产镜像请以本环境 -Xlog:gc* 实测为准。

    为什么小容器体感最强

    小容器往往同时满足「CPU 配额低」和「物理/可见内存偏小」。旧规则下静默走 Serial,停顿模型简单、内存占用观感「省」;27 起默认 G1 后:

    • 并发标记、混合回收节奏会出现,CPU 配额紧张时更易看到 GC 相关 CPU 毛刺。
    • 堆占用曲线与旧 Serial 不完全可比,监控告警阈值可能需要重调。
    • 若脚本曾依赖「小堆=Serial」写死容量规划,需要改为显式 -XX:+UseSerialGC,或接受 G1 并重测。

    紧凑对象头默认开了吗?堆能省多少?

    默认开,堆节省随负载变。

    JEP 534:紧凑对象头

    JDK 27 起,紧凑对象头(Compact Object Headers)默认开启。在 64 位架构上,对象头从约 96 bit 降到 64 bit。若需临时关闭(例如对比实验或排查兼容性):

    -XX:-UseCompactObjectHeaders

    官方表述是该选项 planned for deprecation and removal in a future release,即计划弃用、未来移除,不是「已废弃」。

    堆节省幅度别按固定「少 20%」估算。SPECjbb2015 一类实验场景曾观察到大约 22% 的堆占用节省,但随对象图形状、存活对象比例、分配速率变化;线上请以同负载压测的堆直方图与 RSS 为准。

    与 CDS 归档的关系

    Release notes 提到与紧凑对象头相关的归档命名,例如 classes_coh.jsa、classes_nocoops_coh.jsa。部署时建议直接核对:

    $JAVA_HOME/lib/server/*.jsa

    按实际存在的文件名选择/生成归档,别假定本机一定已有某一文件名。自定义 CDS 流水线若在 JDK 26 生成、在 27 默认开紧凑头的运行时加载,需按版本与头布局重新 dump。

    G1 堆缩放默认:Min/MaxHeapFreeRatio 变成了什么

    仅针对 G1:MinHeapFreeRatio / MaxHeapFreeRatio 默认值从 40/70 调整为 0/100(JDK-8238686,见 JDK 27 GA notes)。含义是:按这对比例约束去做堆缩放的默认行为,基本被关掉。堆不再按旧默认「空闲比例窗口」积极收缩/扩张。

    升级后若你依赖「负载低时堆自动缩小以降 RSS」,需要:

  • 确认收集器确为 G1(27 默认即是)。
  • 若仍要比例缩放,显式设回非 0/100 的比例,并做回归。
  • 结合 -Xms/-Xmx 是否相等:相等时本就少缩放,默认值变化影响更小;不等时影响更明显。
  • 另外,InitiatingHeapOccupancyPercent 已更名为 -XX:G1IHOP(JDK-8227106)。旧名作为已弃用别名仍可能被接受;是否在日志中打印警告,本环境未实测,不做断言。新脚本请优先写 -XX:G1IHOP。

    升级检查清单(小容器优先)

    按顺序做,避免漏项:

  • 钉死 GC 意图:接受 G1 默认,或显式 -XX:+UseSerialGC;别依赖「单 CPU / <1792MB → Serial」的旧启发式。
  • 用同一命令打 GC 日志:java -XX:ActiveProcessorCount=1 -Xmx512m -Xlog:gc*:stdout -version,对比升级前后收集器与关键开关。
  • 确认紧凑对象头:默认开;对比关闭时用 -XX:-UseCompactObjectHeaders;关注平均对象开销与堆水位,不预设固定百分比。
  • 重看堆缩放:G1 下 MinHeapFreeRatio/MaxHeapFreeRatio 默认 0/100;需要缩堆时显式配置并压测 RSS。
  • IHOP 参数名:新配置用 -XX:G1IHOP;清理脚本里的旧名依赖。
  • CDS / AOT 归档:检查 $JAVA_HOME/lib/server/*.jsa,按 release notes 中的 classes_coh.jsa、classes_nocoops_coh.jsa 等命名核对,必要时按 27 默认头布局重生成。
  • 监控与容量:重新标定 GC 暂停 P99、堆使用率告警;小 CPU 配额下关注并发 GC 线程与 ActiveProcessorCount 是否一致。
  • 相关阅读

    • JDK25 Scoped Values
    • Java 虚拟线程瓶颈转移

    配图:默认 GC 选择(旧规则 vs JDK 27)

    默认 GC 选择:旧规则 vs JDK 27

    配图:JDK 27 小容器升级检查清单

    JDK 27 小容器升级检查清单

    赞(0)
    未经允许不得转载:171主机测评 » JDK27升级后小容器GC和内存默认值变了
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址