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,uptime | JDK9+ 统一日志体系 |
| OOM 取证 | -XX:+HeapDumpOnOutOfMemoryError | OOM 时自动导出快照,配 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
线上怎么定(决策顺序)
- 看容器配额:堆要留出堆外余量(元空间、直接内存、线程栈、JIT 开销等),例如 4G 容器堆通常给 2.5G~3G;
- 看业务画像:批处理/大对象业务给大新生代、重吞吐;在线接口关注 P99,用停顿目标约束 GC 行为;
- 看监控反馈:上线后观察 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 快照是线上标配,出事时才不至于抓瞎。