JDK27 9JEP定稿 源码深度解读
7 月 29 日,JDK 27 进入 Rampdown Phase 2,9 个 JEP 全部定稿。Initial Release Candidate 锁定 8 月 6 日,GA 在 9 月 15 日。翻了翻 OpenJDK 的 patch,看几个值得关注的。
G1 默认 GC 从 Server 走向全局
JEP 523 把 G1 设为所有环境的默认 GC,不再区分 Server-Class 和 Client-Class。以前 -XX:+UseG1GC 只在 Server 上自动开启,Client 默认还是 Serial。JDK 27 起就是全局默认值了。
看 OpenJDK 的改动点:
// hotspot/src/hotspot/share/runtime/arguments.cpp (JDK 27)
// 删掉 is_server_class_machine() 判定
if(UseG1GC||FLAG_IS_DEFAULT(UseG1GC)){
// 不再区分 Server/Client,G1 就是默认选择
}
验证方式和回退路径:
java-XX:+PrintFlagsFinal2>&1|grepUseG1GC
# 输出: bool UseG1GC = true
# 小内存(< 2GB 堆)可以切回 Parallel
java-XX:+UseParallelGC-jarapp.jar
G1 在小内存容器里 Region 开销高于 Parallel,这部分是实际切换时需要留意的。
后量子加密握手落地 TLS 1.3
JEP 527 在 JDK 的 TLS 1.3 实现中加入混合密钥交换,NIST 标准化的 ML-KEM(前身 Kyber)和 ML-DSA(前身 Dilithium)首次在 JDK 中原生可用。
// JDK 27 启用 X25519 + ML-KEM 混合密钥交换
System.setProperty("jdk.tls.namedGroups","X25519MLKEM768,secp384r1");
System.setProperty("jdk.tls.client.SignatureSchemes","MLDSA44Ed25519");
SSLContextctx=SSLContext.getInstance("TLSv1.3");
SSLServerSocketFactoryssf=ctx.getServerSocketFactory();
SSLServerSocketserver=(SSLServerSocket)ssf.createServerSocket(8443);
server.setEnabledProtocols(newString[]{"TLSv1.3"});
ML-KEM/ML-DSA 在 AVX-512 上实测性能提升 +60%,来自 OpenJDK Panama Vector 项目在 x86 平台的优化成果。
Compact Object Headers 默认开启
JEP 534(Project Lilliput)把 HotSpot 对象头从 96 位压到 64 位。每个对象省 4 字节,几十 GB 堆的应用整体收益可观。
// hotspot/src/hotspot/share/oops/markWord.hpp (JDK 27)
// 常规布局:96 bits = [mark word: 64] + [klass: 32(压缩)]
// 紧凑布局:64 bits = [mark word + klass 合并]
classmarkWord{
// klass 信息通过偏移量计算,不再独占 32 位
};
运行时验证:
java-XX:+UnlockExperimentalVMOptions-XX:+PrintObjectHeaderLayout
# 输出: Object header size: 8 bytes (compact)
零改代码即可享受微基准上的堆占用降低,尤其适合缓存密集型应用。
Structured Concurrency 第七预览
JEP 533 的第七预览主要做 API 稳定性打磨。核心用法不变:
// JDK 27 Structured Concurrency
voidfetchUserData(StringuserId)throwsException{
try(varscope=newStructuredTaskScope.ShutdownOnFailure()){
Future<String>name=scope.fork(()->queryName(userId));
Future<Integer>orders=scope.fork(()->countOrders(userId));
scope.join();// 等所有子任务
scope.throwIfFailed();// 异常传播
System.out.println(name.resultNow()+" 订单数: "+orders.resultNow());
}
}
与 CompletableFuture 的区别:scope 中所有子任务的生命周期绑定在 try-with-resources 块内,不会产生悬空线程。第七预览增加了 ShutdownOnSuccess 策略的稳定性优化。
Primitive Types in Patterns 第五预览
JEP 532 让 int、long、double 可以直接出现在 instanceof 和 switch 中:
// JDK 27 原始类型模式匹配
Stringclassify(Objectvalue){
returnswitch(value){
caseintiwheni>1000->"大整数: "+i;
caselongl->"长整: "+l;
casedoubled->"浮点: "+d;
casenull->"null";
default->"其他: "+value.getClass().getSimpleName();
};
}
第五预览明确:case int i 不会匹配 null,解决了包装类型拆箱后 null 处理的歧义。
Lazy Constants 第三预览
JEP 531 引入 LazyConstant<T> 接口,延迟初始化但被 JVM 当作真正常量优化:
// JDK 27 Lazy Constants
importjava.lang.constant.*;
class Config{
staticfinalLazyConstant<String>DB_URL=
LazyConstant.of(()->loadFromEnv("DB_URL"));
staticfinalLazyConstant<byte[]>SECRET=
LazyConstant.of(()->{
byte[]key=newbyte[32];
newjava.security.SecureRandom().nextBytes(key);
returnkey;
});
}
JVM 对 LazyConstant 做内联和死代码消除,跟 final 字段同一级别。
其他变更
-noverify/-verifyremote移除:从 JDK 13 弃用到 JDK 27 彻底删除。项目里还留着这两个参数的,直接删掉即可。- JEP 536 JFR 进程内数据脱敏:JFR 录制中命令行参数和环境变量的敏感信息可在流出进程前配置脱敏。
- JEP 537 Vector API 第十二次孵化:
jdk.incubator.vector继续演进,优化 AVX-512 指令生成。 - JEP 538 PEM Encodings 第三预览:标准 PEM 编解码 API,告别手动拼 Base64 边界。
当下能做什么
现在离 GA 还有一个月出头。我建议先上 jdk.java.net/27 拉个 EA 版本,重点跑一下小容器里 G1 的表现——如果堆不到 2GB,考虑加 -XX:+UseParallelGC 回退。TLS 1.3 的命名组配置可以提前在 26 上熟悉,GA 后直接切。IDE 方面 IntelliJ IDEA 2026.2 已经给了 day-one 支持,不用等。9 月 15 见分晓。
夜雨聆风