JVM 调优常用参数有哪些?
更新时间:2026-09-20。问题驱动短答页。第一原则:先测量、后调参,一次只改一个变量。 堆大小怎么定见 JVM 堆内存一般设多少,GC 怎么读见 GC 日志怎么看,频繁 Full GC 见 Full GC 频繁排查。
一句话回答
生产真正高频用到的就五类:堆大小、GC 选择与停顿目标、GC 日志、OOM 留现场、容器内存占比。绝大多数「调优参数」不要从网上抄一大串,先固定基线、用 GC 日志/压测验证再动。
一、堆与元空间
bash
-Xms2g -Xmx2g # 初始堆=最大堆,固定大小避免运行时扩缩容抖动(强烈建议相等)
-Xmn512m # 新生代大小(G1 下通常不手工钉死,让 GC 自适应)
-XX:MetaspaceSize=256m # 元空间初始阈值,达到触发 Full GC,提前设可减少早期扩容
-XX:MaxMetaspaceSize=512m # 元空间上限(JDK8+,替代永久代)
-Xss512k # 每线程栈大小;线程多时调小可省内存,深递归才调大二、GC 相关(JDK 8 / 9+)
bash
# JDK 8 显式选 G1(JDK 9+ 默认就是 G1,可省略)
-XX:+UseG1GC
-XX:MaxGCPauseMillis=200 # G1 停顿目标(只是目标不是保证),别盲目设成 10ms
# GC 日志:JDK 8
-XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:/var/log/gc.log -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=20M
# GC 日志:JDK 9+ 统一 -Xlog
-Xlog:gc*,gc+age=trace,safepoint:file=/var/log/gc.log:time,uptime,level,tags:filecount=5,filesize=20m大堆(>16G)且对停顿极敏感再评估 ZGC/Shenandoah,收集器差异见 G1 与 CMS。
三、OOM 留现场(生产建议默认开)
bash
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/var/log/heap-%p.hprof
-XX:+ExitOnOutOfMemoryError # 或让容器/编排重启,避免僵尸实例继续接流量四、容器环境(最容易踩的坑)
旧版 JDK 不感知 cgroup 会按宿主机内存设堆导致被 OOMKilled。JDK 8u191+/11+ 推荐:
bash
-XX:+UseContainerSupport
-XX:MaxRAMPercentage=50.0 # 堆占容器 limit 的比例;线程多/直接内存大时降到 25~40注意 -Xmx 只管堆,进程总内存还要加 Metaspace + 线程栈 + 直接内存 + JIT,详见 JVM 容器内存限制。
五、一份普通后端服务的基线模板
bash
java -server \
-Xms2g -Xmx2g \
-XX:+UseG1GC -XX:MaxGCPauseMillis=200 \
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/var/log/ \
-Xlog:gc*:file=/var/log/gc.log:time,level,tags:filecount=5,filesize=20m `# JDK9+` \
-Dfile.encoding=UTF-8 \
-jar app.jar六、不要乱加 / 已不推荐
- 网上祖传的几十个
-XX:+UseXXX、-XX:SurvivorRatio、-XX:NewRatio:G1 时代多数不需要手工调,调了反而干扰自适应; -XX:+AggressiveOpts、-Xmx设得远大于实际存活对象(拉长单次 GC、浪费内存);- 只看 GC「次数变少」就认为好了——要看吞吐、单次停顿、P99 RT 和老年代涨势;
- 用盲目扩堆掩盖内存泄漏,泄漏只是更晚爆,OOM 排查 才能根治。
总结
生产 JVM 参数聚焦五类:-Xms=-Xmx 固定堆并合理设元空间/线程栈、显式或默认用 G1 并给合理的 MaxGCPauseMillis、配齐 GC 日志(JDK8 用 PrintGCDetails、JDK9+ 用 -Xlog:gc*)、默认开启 HeapDumpOnOutOfMemoryError 留现场、容器里用 UseContainerSupport 加 MaxRAMPercentage 而非按宿主机设堆;先固定基线、压测和 GC 日志验证、一次改一个变量,G1 下少手工钉新生代和一堆祖传 -XX,绝大多数问题靠修代码/合理容量解决而不是堆参数。