跳到正文
Elaine Blog
返回

JDK 升级与 JVM 性能回归

JVM 与性能

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 线程、内存可见性和诊断工具 用于锁、线程池、虚拟线程与异步任务。


分享这篇文章:

上一篇
GC 调优方法:目标、基线、变更与复测
下一篇
线程生命周期、等待通知与中断协议