JVM参数
JVM 参数用于控制虚拟机运行行为。理解常见参数很重要,但不要把 JVM 调优理解为“背参数大全”。参数应该服务于明确的问题和目标。
# 1. 参数类型
JVM 参数大致分为:
- 标准参数:所有 JVM 实现都应支持,如
-classpath。 - 非标准参数:以
-X开头,如-Xms、-Xmx。 - 高级参数:以
-XX开头,如-XX:+UseG1GC。
高级参数可能随 JDK 版本变化,生产使用前要确认目标 JDK 支持情况。
# 2. 堆参数
常见堆参数:
-Xms2g
-Xmx2g
含义:
-Xms:初始堆大小。-Xmx:最大堆大小。
服务端常将二者设为相同值,减少堆扩缩容抖动。
# 3. 栈参数
-Xss1m
控制每个线程的栈大小。
栈过大:
- 单线程调用深度更大。
- 可创建线程数减少。
栈过小:
- 更容易
StackOverflowError。
# 4. 元空间参数
-XX:MetaspaceSize=256m
-XX:MaxMetaspaceSize=512m
元空间用于存放类元数据。
如果应用大量动态生成类,或者存在类加载器泄漏,可能发生:
OutOfMemoryError: Metaspace
# 5. 直接内存参数
-XX:MaxDirectMemorySize=512m
用于限制直接内存大小。NIO、Netty 等场景需要关注。
如果没有限制,直接内存仍会占用进程总内存,容器环境下尤其要小心。
# 6. GC 参数
选择垃圾回收器:
-XX:+UseG1GC
-XX:+UseZGC
-XX:+UseParallelGC
G1 停顿目标:
-XX:MaxGCPauseMillis=200
不要一开始就调大量 GC 参数。现代 JVM 默认值通常已经不错,应该先收集 GC 日志和业务指标。
# 7. GC 日志参数
JDK 9+:
-Xlog:gc*:file=/data/logs/gc.log:time,uptime,level,tags:filecount=10,filesize=100m
JDK 8:
-XX:+PrintGCDetails
-XX:+PrintGCDateStamps
-Xloggc:/data/logs/gc.log
# 8. OOM 转储参数
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/data/dump
OOM dump 对排查内存泄漏很有价值,但文件可能很大,要确保磁盘空间和数据安全。
# 9. 阶段小结
JVM 参数要围绕目标使用:堆参数控制对象空间,栈参数影响线程和调用深度,元空间参数影响类元数据,GC 参数影响停顿和吞吐。生产调优前应先观测,再调整,再验证。
# 10. 参数配置模板
普通服务端应用可以从类似模板开始,再根据压测调整:
-Xms2g
-Xmx2g
-XX:+UseG1GC
-Xlog:gc*:file=/data/logs/gc.log:time,uptime,level,tags:filecount=10,filesize=100m
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/data/dump
-XX:MaxMetaspaceSize=512m
-XX:MaxDirectMemorySize=512m
这不是通用答案,只是一个思路:
- 固定堆大小,减少扩缩容。
- 使用 G1 作为现代服务端起点。
- 保留 GC 日志。
- OOM 自动 dump。
- 给元空间和直接内存设置边界。
# 11. 参数决策表
| 目标 | 相关参数 | 注意点 |
|---|---|---|
| 控制堆大小 | -Xms、-Xmx | 容器中不能吃满内存 |
| 控制线程栈 | -Xss | 影响线程数量和递归深度 |
| 控制元空间 | MaxMetaspaceSize | 动态类多时要监控 |
| 控制直接内存 | MaxDirectMemorySize | Netty/NIO 场景重要 |
| 选择 GC | UseG1GC、UseZGC | 需压测验证 |
| 记录 GC | -Xlog:gc* | 日志滚动要配置 |
| OOM 留证据 | HeapDumpOnOutOfMemoryError | 注意磁盘和敏感数据 |
# 12. Tips 快问快答
Q:生产环境要不要 Xms=Xmx?
A:多数长期运行服务建议一致,减少堆扩缩容抖动。小工具或弹性场景可另行评估。
Q:MaxGCPauseMillis 设置越小越好吗?
A:不是。过小会让 G1 每次回收太少,可能追不上分配速度。
Q:容器里 -Xmx 应该设置为内存上限吗?
A:不应该。要给元空间、直接内存、线程栈和 JVM 自身留空间。
Q:JVM 参数能运行时修改吗?
A:部分 manageable 参数可以,很多关键参数不能。生产修改前要确认支持情况和风险。
上次更新: 2026/06/24, 16:03:01