JVM 常用参数有哪些?线上堆、栈、GC、日志参数怎么定?

结论先行:JVM 参数按用途可分为四类——堆内存(-Xms/-Xmx)、栈与元空间(-Xss/MetaspaceSize)、GC 选择与目标(-XX:+UseG1GC、MaxGCPauseMillis)、日志与诊断(GC 日志、OOM 快照)。线上“怎么定”没有唯一答案:堆上限取决于容器配额与堆外开销,回收器取决于延迟/吞吐诉求,任何参数都要结合监控数据迭代调整。

常用参数一览表

分类参数示例说明
-Xms4g -Xmx4g初始/最大堆;生产建议两值相等,减少运行期扩容抖动
-Xss512k单线程栈大小;递归较深时可适当调大
元空间-XX:MetaspaceSize=256m类元数据扩容/回收阈值,避免频繁 Full GC
新生代-Xmn2g / -XX:NewRatio=2年轻代大小,或年轻代与老年代比例
GC-XX:+UseG1GC分区式收集器,兼顾吞吐与延迟,JDK9+ 默认
GC 目标-XX:MaxGCPauseMillis=200给 G1 的停顿时间目标
GC 日志-Xlog:gc*:file=gc.log:time,uptimeJDK9+ 统一日志体系
OOM 取证-XX:+HeapDumpOnOutOfMemoryErrorOOM 时自动导出快照,配 HeapDumpPath 指定路径

启动示例

java -Xms4g -Xmx4g -Xss512k \
     -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m \
     -XX:+UseG1GC -XX:MaxGCPauseMillis=200 \
     -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/logs/oom.hprof \
     -jar app.jar

线上怎么定(决策顺序)

  1. 看容器配额:堆要留出堆外余量(元空间、直接内存、线程栈、JIT 开销等),例如 4G 容器堆通常给 2.5G~3G;
  2. 看业务画像:批处理/大对象业务给大新生代、重吞吐;在线接口关注 P99,用停顿目标约束 GC 行为;
  3. 看监控反馈:上线后观察 Young/Old 水位与 YGC/FGC 频率,把“CPU 换延迟”的取舍量化成指标再调参。

代码里验证生效参数

// 运行时打印堆信息,确认参数是否按预期生效
Runtime rt = Runtime.getRuntime();
System.out.println("max heap = " + rt.maxMemory() / 1024 / 1024 + " MB");
System.out.println("total heap = " + rt.totalMemory() / 1024 / 1024 + " MB");

常见追问 / 记忆点

  • 追问:G1 和 CMS 怎么选?答:JDK9+ 默认 G1、CMS 已废弃;追求超低延迟再看 ZGC/Shenandoah。
  • 追问:-Xmx 与 -Xms 不一致会怎样?答:堆会动态伸缩,扩容缩容可能带来 GC 抖动与性能毛刺,线上一般设相等。
  • 记忆点:参数四件套“堆、栈、GC、日志”;GC 日志与 OOM 快照是线上标配,出事时才不至于抓瞎。
笔记加载中…