JDK 17:JVM 与运行时更新#
版本信息
本页讲 「工具与运行时」 桶。语言特性见 概览。
运行时主线#
JDK 17 的 JVM 层头条是:两台低延迟 GC 从实验转正为产品级——ZGC(JEP 377)与 Shenandoah(JEP 379),都在 JDK 15 完成,17 LTS 承接。这意味着低延迟 GC 进入"生产可用"阶段,不再需要解锁实验开关。
ZGC 转正为产品#
为什么需要#
ZGC(Z Garbage Collector)把绝大部分回收工作与应用线程并发进行,停顿通常 <1ms 且不随堆大小增长(TB 级堆仍保持低停顿)。在 JDK 11 它还只是实验特性(且需特定构建),到 JDK 17 已是正式 GC。
怎么用#
一个标志即可,无需解锁(本机实测 JDK 17 直接可用):
java -XX:+UseZGC -Xmx16g -jar app.jar
下面是 examples/zgc/ 里真实可运行的演示(snippets 嵌入,零漂移):
package com.javamodern.zgc;
import java.lang.management.GarbageCollectorMXBean;
import java.lang.management.ManagementFactory;
import java.util.List;
import java.util.stream.Collectors;
/**
* 演示 ZGC:可扩展低延迟垃圾收集器(JEP 377,JDK 15 转正,17 LTS 可用)。
*
* <p>ZGC 是并发 GC,回收大部分工作与应用线程并发进行,MXBean 名为
* {@code "ZGC Cycles"}(并发周期)与 {@code "ZGC Pauses"}(短暂 STW 停顿)。
* 测试 JVM 必须以 {@code -XX:+UseZGC} 启动(见 {@code pom.xml} 的 surefire {@code argLine})。
*/
public class ZgcDemo {
/** 当前所有 GC MXBean 的名字。 */
public static List<String> gcNames() {
return ManagementFactory.getGarbageCollectorMXBeans().stream()
.map(GarbageCollectorMXBean::getName)
.collect(Collectors.toList());
}
/** 是否运行在 ZGC 下(任一 bean 名含 "ZGC")。 */
public static boolean isZgc() { // (1)
return gcNames().stream().anyMatch(n -> n.contains("ZGC"));
}
public static void main(String[] args) {
System.out.println("GC beans = " + gcNames());
System.out.println("isZGC = " + isZgc());
}
}
- :material-lightbulb: 通过 GC MXBean 名判定当前 GC:ZGC 的 bean 是
ZGC Cycles(并发周期)与ZGC Pauses(短暂 STW 停顿)——两个 bean 的并存体现了它"并发为主、偶发短停顿"的结构。
运行 ZgcDemo.main 的实测输出(JDK 17 + ZGC):
GC beans = [ZGC Cycles, ZGC Pauses]
isZGC = true
底层原理#
graph LR
App["应用线程运行"] -.并发.- C["并发标记/转移<br/>colored pointers + load barriers"]
App --> P["极短 STW 停顿<br/>仅初始标记/再标记等几个点"]
C --> D["堆可达性更新"]
P --> D
style App fill:#c8e6c9
style P fill:#ffe0b2
style C fill:#bbdefb
关键技术:染色指针(colored pointers) 在 64 位指针里编码对象状态,读屏障(load barrier) 在应用线程访问对象时并发完成转移——这让大部分回收无需 Stop-The-World。
Shenandoah 转正(发行版差异)#
Shenandoah(Red Hat 主导)也在 JDK 15 转正(JEP 379),思路与 ZGC 类似(并发整理,低停顿),技术细节不同(用 Brooks 指针 / 转发指针而非染色指针)。
发行版差异(本机实测)
本机所有构建(Oracle JDK 17、OpenJDK 11/21)都不含 Shenandoah:-XX:+UseShenandoahGC 报 Unrecognized VM option。Shenandoah 主要出现在 Red Hat / Fedora / Amazon Corretto 等构建中。选 GC 前先确认你的 JDK 发行版是否包含目标 GC。
其他运行时更新#
| 特性 | JEP | 说明 |
|---|---|---|
| macOS/AArch64 移植 | 391 | Apple Silicon(M1/M2)原生支持 |
| macOS Metal 渲染 | 382 | Swing/Java2D 在 macOS 上改用 Metal,替代已废弃的 OpenGL |
| Security Manager 弃用 | 411 | 标记 Security Manager 为移除候选——它已不适应现代安全模型,未来版本将移除 |
| 增强型 PRNG | 356 | (标准库)新增 java.util.random.RandomGenerator 统一接口与可跳变/流式 PRNG |
与 JDK 8 对比#
java -jar app.jar # 默认 Parallel;或手动 -XX:+UseG1GC
# 没有停顿 <1ms 的并发 GC 可选
java -XX:+UseZGC -Xmx16g -jar app.jar # 产品级低延迟,一个标志
java -jar app.jar # 仍是默认 G1
常见坑 / 最佳实践#
- ZGC 不等于更快:它降的是停顿,不是吞吐;吞吐型批处理用 G1/Parallel 可能更高。按负载选。
- GC 选型看发行版:要 Shenandoah 得选 Red Hat 系构建;要 ZGC 大多数 OpenJDK 构建都有。
- Oracle JDK 17 的免费窗口:Oracle JDK 17 的免费商用更新窗口有限且会过期;长期使用建议改用 OpenJDK 衍生发行版(Temurin/Corretto/Zulu 等),升级规划时把"换发行版"纳入考虑。
- 大堆 + 低延迟:ZGC 的停顿几乎与堆大小无关,几十 GB~TB 堆仍能保持亚毫秒停顿——这是它相对 G1 的核心优势。
小结#
JDK 17 的 JVM 更新主线是「低延迟 GC 转正」:ZGC、Shenandoah 从实验走向产品级,停顿可控性跃升;平台层面补齐了 Apple Silicon 支持。对企业升级,这意味着大堆、低延迟负载有了开箱即用的方案。