# Java 27 生产就绪，你的升级流程跟得上吗？

**Summary:** OpenJDK 发布了包含九个 JEP 的 JDK 27 build 35，并更改了两个运行时默认值。我会立即在 CI 中使用它，但只有在测量这些默认值并安排好下一次升级后才会在生产环境中推广。

- Canonical: https://markhuang.ai/zh/news/java-27-production-ready-upgrade-process
- Language: zh-CN
- Author: [Mark Huang](https://markhuang.ai/about)
- Published: 2026-09-15
- Section: News
- Tags: Java 27, OpenJDK, JVM, 垃圾回收, 软件升级
- Source: [OpenJDK Announce](https://mail.openjdk.org/archives/list/announce@openjdk.org/thread/ORGGLMN75HFEWP7YL3ZLGHLYHVIBJDYT/)
- License: https://creativecommons.org/licenses/by-nc/4.0/

---

![服务器运行时将零散的内存块整理压缩，绿色回收器将其归拢为更紧凑的布局](https://cdn.markhuang.ai/news/java-27-production-ready-upgrade-process/hero.webp)

*Java 27 动的是应用底层的运行机理。代码一行没改，内存布局和垃圾回收却已经变了。*

[OpenJDK 的 Java 27 公告](https://mail.openjdk.org/archives/list/announce@openjdk.org/thread/ORGGLMN75HFEWP7YL3ZLGHLYHVIBJDYT/)说得干脆：JDK 27 build 35 已正式发布，可以上生产了。这个构建在 2026 年 8 月 20 日成为第二个发布候选版本，直到 9 月 15 日正式发布前也没有报出任何 P1 级别的 bug。最终版本打包了九个 JEP。

但我的看法没这么干脆。我会现在就把 Java 27 推进 CI。至于生产服务，得看团队能不能量出两个运行时默认值的变化，并且愿意按供应商的节奏再做一次 JDK 选型。“生产就绪”说的是 OpenJDK 团队交付了什么，不是说你的升级流程跟不跟得上。

## "生产就绪"把维护问题留给了你

这个区别很关键。Java 27 是 Oracle 两个 LTS 版本之间的功能版本。Oracle 的[Java SE 支持路线图](https://www.oracle.com/java/technologies/java-se-support-roadmap.html)把 JDK 27 标成非 LTS，Premier Support 只给到 2027 年 3 月。这个日期说的是 Oracle 自家的商业 JDK，不是所有 OpenJDK 发行版，但它把运营问题摆到了桌面上：我要部署哪个供应商的构建？这个供应商会维护多久？

这个问题马上就在[Java 27 发布帖](https://www.reddit.com/r/java/comments/1wgdo1p/java_27_launch_stream/)里冒出来了。有开发者问 JDK 26 还有多少支持。Java 团队成员回复说，27 发布之后 26 就不会再有任何更新了。在[另一个讨论](https://www.reddit.com/r/java/comments/1usjg5d/java_27_whats_new/)里，开发者们说他们在等 JDK 29，因为公司只在 LTS 版本之间迁移。我理解这种谨慎，但这可能把六个月的发布周期拖成好几年的意外。

我会把这两个选择拆开。团队可以测试每个功能版本，但不必承诺在生产里跑每一个。这样能让库、构建插件、容器镜像和可观测性工具保持兼容，同时保留更慢的部署节奏。

## 这次发布的主角是默认值

功能列表里有 TLS 1.3 的后量子混合密钥交换、结构化并发的又一轮预览、Vector API 的第十二轮孵化。这些自然吸引眼球。但两个默认值改动更绕不开——它们在你还没碰任何新 API 之前，就已经改变了运行时行为。

[JEP 534](https://openjdk.org/jeps/534) 默认开启紧凑对象头。在 64 位架构上，对象头从 96 位缩到 64 位。老布局还能用 `-XX:-UseCompactObjectHeaders` 打开，所以这个改动可以回退。OpenJDK 给出的基准测试结果不错，其中一个 SPECjbb2015 场景堆占用降了 22%，CPU 时间降了 8%。但这些是拿来测试的证据，不是直接贴进生产容量规划的数字。

[JEP 523](https://openjdk.org/jeps/523) 让 G1 成为所有环境下的默认垃圾回收器。从 JDK 9 开始，HotSpot 在单 CPU 或物理内存不到 1,792 MB 的机器上会自动选 Serial GC。Java 27 把这个例外拿掉了。现在不管你有多少核、多少内存，只要没显式指定，HotSpot 一律选 G1。

## 从小型容器开始

正因为 G1 的这个变化，我不会从最大的服务开始。大型服务器部署已经用了好几年 G1 默认值。真正值得测的是那些之前刚好踩到 HotSpot 受限环境阈值的小东西——sidecar、定时任务、边缘进程、低内存容器。

我会把新旧 JDK 下实际选的回收器记下来，然后在容器真实限制下比启动时间、常驻内存、CPU、暂停表现、请求延迟。如果 Serial 跑得更好，Java 27 照样可以显式指定它。G1 本身很成熟。真正要避免的坑是：老版本运行时本来选的是 Serial，你升级后一声不吭就接受了 G1 的默认值。

紧凑对象头也得用同样的纪律来对待。堆变小了确实可能减轻 GC 压力，但真正有用的数字是：在我的工作负载、我的正常分配速率下，到底变了多少。我要的是灰度结果和回退开关，不是基准测试里的漂亮故事。

## 安全方面有个改动值得欢迎

[JEP 536](https://openjdk.org/jeps/536) 改了 JDK Flight Recorder 的数据输出方式——数据离开进程之前，JFR 会默认对命令行参数、环境变量和系统属性中可能包含的敏感信息做脱敏处理。团队可以扩展过滤规则（不区分大小写）、从文件加载规则，排查问题需要原始值时也可以关掉脱敏。

这解决了一个很实际的问题：诊断录制的文件可能流进归档系统或者提交给技术支持，里面却带着 access token 和密码。默认脱敏直接降低了这种泄露风险。不过我还是会拿自己公司的密钥名称去测一遍——模式匹配不可能覆盖所有内部命名习惯，依赖原始值的工具也得检查一遍。

[Java 团队的运行时说明](https://inside.java/2026/09/12/jdk-27-runtime-updates/)还提到了一些被移除的 JVM 选项、JSON 线程转储的格式版本变化，以及实验性的 JVM Compiler Interface 被拿掉了。这些细节比"九个 JEP"的标题更适合拿来当迁移清单。启动脚本和解析器经常会写死一些老行为，过了很久谁都不记得当初为什么这么写了。

## 我对 Java 27 的态度

我会把 Java 27 当成一次升级体系的审计工具。现在就拿它编译、跑测试。然后挑最小的、最接近生产形态的工作负载去跑。在正式推之前，把 JDK 供应商、更新策略、基础镜像可用性、下一次迁移日期都确认清楚。

> **Info:**
>
> 我的原则：Java 27 的默认值改动跑出了可量化的结果，而且下一次升级已经有人负责了，再上生产。否则，拿 27 来提前暴露兼容性问题——趁下一个 LTS 来之前还有时间修。

Java 27 能上生产当然是好消息。但对我来说，它眼下最大的价值是帮你发现应用、构建链和运维工具对运行时有哪些想当然的假设。生产集群可以按自己的节奏走，CI 紧跟每个功能版本就够了——赶在这些假设变成迁移事故之前把它们揪出来。
