Java

JVM 参数优化

·7 分钟阅读·2756 字

JVM 内存参数优化——黄金原则、标准配置、内存计算公式、GC 选型、故障排查

📋 目录

JVM 参数优化

运维版 JVM 内存参数优化——直接落地、不玄学。涵盖黄金原则、标准启动参数、内存计算、GC 选型、常见问题优化。 我给你纯生产实战、运维能直接用的 JVM 内存优化方案,不讲理论废话,只讲:
怎么配、配多少、怎么看、怎么调

你只要按这套流程走,99% 的 Java 应用都能稳定运行。


一、先记住:JVM 内存优化的 4 个黄金原则

  1. 堆内存 = 业务需要 + 预留空间,不能太小,也不能无限大
  2. -Xms = -Xmx(强制相等,避免扩容卡顿)
  3. 新生代不能太小(太小会导致对象过早进入老年代 → Full GC)
  4. 元空间必须设上限(防止吃满服务器内存)

二、最标准、最通用、最安全的 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(最严重)

原因:

  • 新生代太小
  • 堆太小
  • 内存泄漏

优化:

  1. 加大堆
  2. 加大新生代
  3. 切换 G1
  4. 分析 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 秒总结(运维背这一段就够)

  1. -Xms = -Xmx
  2. 堆 ≤ 服务器内存 * 0.6
  3. 新生代 = 堆的 1/3
  4. 元空间 256~512m
  5. GC 用 G1
  6. 必须开 GC 日志 + OOM dump
  7. FGC 小时级正常,分钟级必须优化
  8. YGC 频繁 = 新生代太小


关联文档