GC 调优的目标

GC 调优一般是为了:

  • 降低内存占用
  • 降低延迟
  • 增加吞吐量

当然,很难三者都兼顾;一般只能侧重其中一两个。

有时候 GC 参数不合理会导致 OOM,这时候也需要调优。

 

GC 调优的一般思路

1. 根据实际应用场景确定调优目标

如,GC 停顿时间不能大于200ms,同时吞吐量不能低于每秒 1W 次请求。

所以 GC 调优是非常考验个人技术经验的。如果没有丰富的实践经验作为决策依据,很可能会出一些“拍脑袋”的不现实目标。

 

2. 分析 JVM 中 GC 的状态,定位问题原因,以确定是否有调优的必要

一般可以通过 jstat 等JVM监控工具、GC日志、操作系统诊断工具等获取JVM相关信息。

如,发现应用在某段时间响应很慢时,可以查看这段时间的GC日志,是否有GC导致长时间的停顿。

也得区分是 Minor GC 耗时过长,还是 Mixed GC 耗时过长。

 

 

3. 确定使用哪种 GC

如果应用系统当前所使用的 GC 不符合应用服务特征,就得更换GC。

如,CMS 和 G1 都是更侧重于 低延迟 的GC;Parallel GC 是侧重于 吞吐量 的GC。

如果当前 GC 符合应用特征,那就得考虑更深入的配置调优。

 

4. 根据实际情况调整相关 JVM 参数或其它软硬件配置

 

5. 验证调整后的应用已满足目标

如果已达到目标,则结束调优;如果不满足则需重复分析、调整并验证

 

GC 调优的一般原则

尽量升级到新的 JDK

很多JVM相关问题,在新的 JDK 已经修复或避免。通常而言,升级 JDK 是最好的解决方案。

很多软件组织名为“以稳定为主,保障安全”,实为“缺乏技术能力,缺乏担当”,所以迟迟不升级 JDK。害了不少人。

 

做好 GC 相关信息的收集

利用 JVM 参数可以获得 GC 相关信息

  • -XX:+PrintGCDetails
  • JDK 9 中,该选项已被标记为废弃
  • 从 JDK 9 开始,可以用 -Xlog:gc 指定相关 GC 日志的记录方式
  • 如,指定记录 trace 级别的 GC 日志,日志文件名为 gc.txt,日志文件数最多6个,每个日志文件最大1MB:
  • -Xlog:gc=trace:file=gc.txt::filecount=5,filesize=1m
  • 6个日志文件:gc.txt、gc.txt.0、gc.txt.1、gc.txt.2、gc.txt.3、gc.txt.4
  • 另,可用 java -Xlog:help 查看更多 JVM 日志选项
  • -XX:+PrintGCDateStamps
  • JDK 9 中,该选项已被移除;可以使用 -Xlog:gc
  • -XX:+PrintAdaptiveSizePolicy
  • GC 的某些行为是根据运行时情况适应性触发的。通过查看该参数相关功能返回的GC信息,有助于我们理解为什么GC出现了我们不希望发生的操作。
  • -XX:+PrintReferenceGC
  • 如果怀疑引用清理不及时,通过这些信息可以发现哪里出现了堆积情况
  • JDK 9 开始,可以用 -Xlog:gc+ref
  • 另外,可以通过 -XX:+ParallelRefProcEnabled 开启对引用的并行处理