JVM 参数优化
运维版 JVM 内存参数优化——直接落地、不玄学。涵盖黄金原则、标准启动参数、内存计算、GC 选型、常见问题优化。 我给你纯生产实战、运维能直接用的 JVM 内存优化方案,不讲理论废话,只讲:
怎么配、配多少、怎么看、怎么调。
你只要按这套流程走,99% 的 Java 应用都能稳定运行。
一、先记住:JVM 内存优化的 4 个黄金原则
- 堆内存 = 业务需要 + 预留空间,不能太小,也不能无限大
- -Xms = -Xmx(强制相等,避免扩容卡顿)
- 新生代不能太小(太小会导致对象过早进入老年代 → Full GC)
- 元空间必须设上限(防止吃满服务器内存)
二、最标准、最通用、最安全的 JVM 启动参数(直接复制用)
适合 99% 项目(SpringBoot、微服务、中间件)
# 1. 堆内存(核心)
-Xms9g # 初始堆
-Xmx9g # 最大堆(和 -Xms 一样)
# 2. 新生代(推荐:堆的 3/8 ~ 1/2)
-Xmn3g # 新生代大小(推荐 堆的 1/3 左右)
# 3. 元空间(JDK8+)
-XX:MetaspaceSize=256m
-XX:MaxMetaspaceSize=512m
# 4. 线程栈
-Xss256k
# 5. GC 收集器(JDK8 推荐 G1)
-XX:+UseG1GC
-XX:MaxGCPauseMillis=200 # 期望最大停顿 200ms
# 6. GC 日志(必须开!排查必备)
-XX:+PrintGCDetails
-XX:+PrintGCDateStamps
-XX:+PrintGCTimeStamps
-Xloggc:/opt/logs/gc.log
# 7. OOM 自动 dump(救命参数)
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/opt/logs/heap.hprof
这一套就是生产标准优化参数。
三、JVM 内存到底怎么计算?(运维最需要的公式)
1. 堆内存怎么给?
规则:
Java 进程总内存 ≈ 堆 (-Xmx) + 元空间 + 线程栈 + 堆外内存 + 系统预留
经验公式(最实用):
-Xmx ≤ 服务器内存 * 0.6
例子:
- 16G 服务器 → 给 9G 堆
- 8G 服务器 → 给 4G~5G 堆
- 4G 服务器 → 给 2G 堆
为什么不能给 80% 以上?
因为元空间、线程栈、堆外内存、系统本身都要吃内存。
2. 新生代怎么给?
最简单规则:
新生代 = 堆的 1/3 左右
- 堆 9G → 新生代 3G
- 堆 6G → 新生代 2G
- 堆 4G → 新生代 1.5G
为什么?
新生代太小:
- 对象活不久就进入老年代
- 引发 频繁 Full GC → 卡顿、超时、雪崩
新生代太大:
- Minor GC 时间变长
- 停顿变大
1/3 是最平衡的。
3. 元空间怎么配?
固定 256m ~ 512m 足够绝大多数项目!
-XX:MetaspaceSize=256m
-XX:MaxMetaspaceSize=512m
只有这些场景需要加大:
- 热部署
- 大量动态代理(MyBatis、CGLIB)
- Groovy/JRuby 等动态语言
- 超大型项目(10万+类)
→ 最大配到 1g 顶天了。
4. 线程栈 -Xss
默认 1M,生产推荐 256k 或 512k
-Xss256k
-Xss 越小:
- 能创建的线程越多
- 不容易出现
unable to create thread
四、GC 收集器怎么选?(运维一句话搞定)
JDK8
用 G1GC(推荐)
-XX:+UseG1GC
JDK11+
ZGC(低延迟神器)
-XX:+UseZGC
批处理任务、离线计算
Parallel GC(高吞吐量)
-XX:+UseParallelGC
五、怎么判断 JVM 内存是否需要优化?(看 3 个指标)
1. 看 GC 频率(最关键)
jstat -gc <pid> 1000
重点看:
- YGC:1秒 ~ 几秒一次 正常
- FGC:小时级才正常,分钟级就是有问题
坏现象:
- FGC 几分钟一次 → 内存参数不合理 / 内存泄漏
- YGC 每秒好几次 → 新生代太小
2. 看 GC 后老年代是否持续上涨
jstat -gcutil <pid> 1000
- 老年代使用率不断涨 → 内存泄漏
- 老年代涨得快 → 新生代太小,对象过早晋升
3. 看 GC 停顿时间
G1 目标:
-XX:MaxGCPauseMillis=200
实际 GC 停顿 > 500ms → 要优化
六、最常见 4 类 JVM 问题 + 最优优化方案
1. 频繁 Full GC(最严重)
原因:
- 新生代太小
- 堆太小
- 内存泄漏
优化:
- 加大堆
- 加大新生代
- 切换 G1
- 分析 dump
2. 频繁 Minor GC
原因:新生代太小
优化:
直接加大新生代(-Xmn)
3. 应用卡顿、接口超时
原因:
- Full GC 停顿
- 新生代太大导致 YGC 停顿长
优化:
- 用 G1/ZGC
- 控制新生代在堆的 1/3
4. 元空间 OOM
原因:动态类太多、热部署
优化:
-XX:MaxMetaspaceSize=512m
七、不同服务器配置 → 直接给你最优内存参数
1)服务器 4C8G → 最常用
-Xms4g -Xmx4g -Xmn1536m
-XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m
-Xss256k
-XX:+UseG1GC
2)服务器 8C16G
-Xms9g -Xmx9g -Xmn3g
-XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m
-Xss256k
-XX:+UseG1GC
3)服务器 16C32G
-Xms18g -Xmx18g -Xmn6g
-XX:MaxMetaspaceSize=512m
-XX:+UseG1GC
八、JVM 内存优化 10 秒总结(运维背这一段就够)
- -Xms = -Xmx
- 堆 ≤ 服务器内存 * 0.6
- 新生代 = 堆的 1/3
- 元空间 256~512m
- GC 用 G1
- 必须开 GC 日志 + OOM dump
- FGC 小时级正常,分钟级必须优化
- YGC 频繁 = 新生代太小
关联文档
- JVM 内存结构 — JVM 运行时数据区详解
- JVM 学习路线与故障排查 — 线上故障排查与学习路线