JDK 升级性能验证必须使用同一产物、负载和资源,分别比较启动阶段与稳定阶段。只跑一次平均值既看不见预热差异,也无法 区分随机波动和真实回归。
Table of contents
Open Table of contents
先分离运行时升级和源码升级
第一轮让同一个 Java 17 --release 产物分别运行在 JDK 17、21 和 25。它主要验证运行时、GC、JIT 和库兼容性。
第二轮再用新 JDK 重新编译,并单独评估新语言/API 与 Class 版本变化。
这样能回答“回归来自运行时还是重新编译”,也能保留更简单的回滚路径。
建立实验矩阵
| 变量 | 必须固定或记录 |
|---|---|
| 应用 | Git 提交、依赖锁、配置、数据 |
| 运行时 | 发行版、完整 JDK 补丁版本、镜像摘要 |
| 资源 | CPU、内存、NUMA、容器限制 |
| 负载 | 请求分布、并发、持续时间、预热 |
| JVM | 最小参数、最终 Flags、收集器 |
| 输出 | 吞吐、延迟、CPU、RSS、GC、JFR |
不要把旧 JDK 的一长串调优参数原样带入新 JDK 基线。参数可能被移除、默认值可能变化,也可能阻止新版本的自适应优化。
分开测启动和稳定状态
启动性能包括进程启动、类加载、JIT 预热、连接池和缓存就绪时间。稳定性能应在吞吐和编译活动趋稳后采集。对每个版本 至少运行多次独立进程,报告中位数、分位数和离散程度。
微基准使用 JMH 并配置多个 Fork;端到端压测则同时保存压测端和服务端指标。若结果差异小于自然波动,不要宣布“提升”。
检查兼容与默认值变化
升级前运行:
jdeps --jdk-internals app.jar
java -XX:+PrintFlagsFinal -version > flags.txt
java -Xlog:os+container=trace -version
对比收集器、堆计算、CPU 识别、字符集、时区数据、安全协议、JIT 编译和 Agent 支持。Oracle 的
JDK 25 迁移准备指南建议先在新 JDK 运行旧产物,
再升级依赖、重新编译并使用 jdeps 检查内部 API。
设置发布门禁与回滚
门禁应同时限制功能错误、P99、吞吐、CPU、RSS、GC 暂停和启动时间。灰度发布先比较同一流量下的新旧实例;指标超过 阈值时自动停止扩容并保留 JFR、GC 日志和部署参数。
回滚前要确认新版本没有写出旧版本无法读取的数据、序列化格式或缓存内容。运行时可回滚不代表数据行为可回滚。
下一步
继续阅读并发与异步编程阶段,把 JVM 线程、内存可见性和诊断工具 用于锁、线程池、虚拟线程与异步任务。