Skip to content

JVM 性能优化指南(GC 调优)

JVM 调优不是玄学,而是一个循环:测量 → 只改一件事 → 验证。本篇给你工作流、"症状 → 对策"对照表,以及真正重要的那几个参数。

第一步:动手之前先测量

永远不要盲调。先开启 GC 日志(生产安全,开销 < 3%),并分析一个覆盖业务高峰的时间窗口:

bash
# Java 9+
java -Xlog:gc*:file=gc.log:time,uptime -jar app.jar
# Java 8
java -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:gc.log -jar app.jar

用 EasyGC 分析日志 →

报告会告诉你,你面对的是下面四种典型问题中的哪一种。

第二步:症状对对策

报告中的症状可能原因尝试方案
Full GC 频繁老年代过小 / 内存泄漏 / 缓存过大调大 -Xmx;排查泄漏(GC 后堆逐级抬升);审视缓存容量
分配速率过高短命对象风暴热点路径对象池化 / 缓存;减少每请求垃圾
最大停顿超过 SLO回收器不对或堆太大换 G1/ZGC;G1 设置 -XX:MaxGCPauseMillis
吞吐量 < 90%回收频率过高加大年轻代(-Xmn / -XX:NewRatio);加大堆
元空间触发 GC类加载风暴调大 -XX:MaxMetaspaceSize;排查动态代理
原因里有 System.gc()显式调用(RMI/NIO)-XX:+DisableExplicitGC——先确认无 Direct ByteBuffer 依赖
G1 巨型对象分配对象超过分区一半调大 -XX:G1HeapRegionSize;优化大数组设计

第三步:一次只改一个参数

调一项、重新分析、对比报告——这是确认有效性的唯一方式。覆盖 90% 场景的参数:

参数作用
-Xms = -Xmx固定堆大小——消除伸缩停顿,行为更可预测
-Xmn / -XX:NewRatio年轻代大小——控制 GC 频率的主杠杆
-XX:+UseG1GC / -XX:+UseZGC回收器选择——控制停顿长度的主杠杆
-XX:MaxGCPauseMillis=200G1 停顿目标(别设得脱离现实)
-XX:MaxMetaspaceSize类元数据上限
-XX:+DisableExplicitGC忽略 System.gc() 调用

第四步:验证并留下基线

重新分析新的 GC 日志,与旧报告对比:吞吐量升了吗?最大停顿降了吗?Full GC 消失了吗?把两份报告(PDF/JSON)存档作为基线——下次发版后分析一次,就知道 GC 行为有没有回退。

检查清单

TIP

术语还不熟?先看 JVM、JRE、JDK 的区别,再回来继续。

相关文章