跳到正文
Elaine Blog
返回

GC 调优方法:目标、基线、变更与复测

JVM 与性能

GC 调优不是收集参数,而是一个可证伪实验:定义业务目标,记录基线,识别限制因素,只改变一个变量,再用相同负载复测。 如果没有可重复负载和回滚方案,先不要改参数。

Table of contents

Open Table of contents

定义四类目标

每次调优至少记录这些指标:

目标示例证据来源
业务延迟P99 < 120 ms入口请求指标
GC 暂停暂停 P99 < 40 msGC 日志、JFR
吞吐≥ 2,000 RPS压测端与服务端
资源CPU < 70%,RSS < 3 GiB容器与系统指标

平均延迟不能替代尾延迟。只优化暂停也可能降低吞吐、增加 CPU 或扩大内存占用。

建立基线

固定 JDK、镜像、参数、数据集、流量模型、预热时间和运行时长。收集:

先查代码层问题:无限缓存、超大批次、重复序列化和一次性加载全量数据,通常不能靠 GC 参数修好。

一次只改一个决策

常见实验顺序如下:

  1. 确认堆预算能容纳稳定存活集和分配波动,并给 Native 内存留余量。
  2. 使用目标 JDK 的默认收集器运行基线。
  3. 若暂停目标不满足,确认长暂停阶段和对象原因。
  4. 只修改一个主要变量,例如堆大小、收集器或 G1 暂停目标。
  5. 运行相同负载,比较完整指标并执行至少一次重复实验。

G1 的 MaxGCPauseMillis 是软目标,不是硬实时保证。把它设置得很小可能缩小年轻代、增加收集频率并降低吞吐。JDK 25 的 G1 调优说明建议先移除 不必要的固定年轻代参数,让 G1 自适应。

保存实验记录

假设:长暂停来自 Humongous 对象分配导致的提前并发周期
基线:JDK 25.0.x,G1,Xmx=2g,P99=...,暂停 P99=...
变更:把批次缓冲从 2 MiB 拆成 256 KiB;JVM 参数不变
结果:Humongous 分配下降 ...%,P99 变为 ...
结论:接受/拒绝;回滚方式:恢复提交 ...

调优结论必须包含测试条件和失败结果。否则下一位维护者会重复同一实验或把参数复制到完全不同的服务。

下一步

阅读JDK 升级与 JVM 性能回归,把同一实验用于版本迁移门禁。


分享这篇文章:

上一篇
常量池、字符串与类元数据的内存代价
下一篇
JDK 升级与 JVM 性能回归