JVM之参数与调优
一、堆内存核心参数
-Xms初始堆内存,生产建议 =Xmx,避免运行时动态扩容卡顿
-Xmx最大堆内存,防止 OOM,根据服务器配置合理设置
-Xmn新生代整体大小(Eden+2 个 Survivor)
-XX:NewRatio老年代 / 新生代 比例
例:
NewRatio=2老年代:新生代 = 2:1-XX:SurvivorRatioEden / 单个 Survivor 比例
例:
SurvivorRatio=8Eden:S0:S1 = 8:1:1
二、元空间参数
-XX:MetaspaceSize元空间初始阈值,触发首次元空间 GC
-XX:MaxMetaspaceSize元空间最大值,防止元空间溢出
JDK8 永久代取消,改用元空间,直接使用本地内存
三、GC 收集器 & 性能参数
- G1 相关
-XX:+UseG1GC启用 G1 收集器-XX:MaxGCPauseMillis=200目标最大停顿时间
- ZGC 低延迟
-XX:+UseZGC启用 ZGC(JDK11+)
- 通用 GC 配置
-XX:+PrintGCDetails打印 GC 详细日志-XX:+HeapDumpOnOutOfMemoryErrorOOM 自动 dump-XX:HeapDumpPath指定 dump 文件路径
是否开启GC日志
不开
生产环境:默认 不开启 GC 日志
GC 日志会持续刷盘,产生磁盘 IO、占用存储空间
开
接口频繁卡顿、延迟抖动
时不时 CPU 飙高、定时慢请求
频繁 FullGC、内存波动大
压测环境、性能测试环境
无事不开,有事再开。
折中最优方案(企业通用)
平时关闭 GC 日志,出问题临时开启,无需重启服务
JDK8 支持动态开关:
1 | |
四、调优三大核心目标
降低 GC 频率
合理分代大小,减少短周期 Minor GC、避免频繁扩容
缩短 STW 停顿
选用低延迟收集器:G1 / ZGC,限制最大暂停时间
杜绝 Full GC & OOM
控制老年代增长、限制元空间、合理设置堆上限、排查内存泄漏
五、标准调优步骤
监控
jstat、GC 日志、VisualVM、Arthas 采集运行数据
分析
定位:频繁 GC、STW 过长、老年代暴涨、元空间溢出、堆外内存泄漏
参数调整
调堆大小、分代比例、更换收集器、优化内存区域阈值
压测验证
调整后压测回归,观察 GC 指标、吞吐量、响应时间、CPU 负载
六、生产常用基础配置模板
1 | |
一、宿主机启动参数(直接运行 jar 包)
最终命令
1 | |
逐条解析(宿主机版)
1 | |
初始化堆 512M,最大堆 512M(宿主机固定配置最稳定)
1 | |
使用 G1 垃圾回收器(低延迟、适合 SpringBoot)
1 | |
GC 最大停顿 200ms,避免接口卡顿
1 | |
禁止代码里手动 System.gc (),避免无故卡顿
1 | |
内存溢出直接退出,方便自动重启恢复
1 | |
OOM 时自动导出内存快照,方便排查泄漏
1 | |
解决随机数阻塞,启动飞快
1 | |
统一编码,防止中文乱码
1 | |
优雅停机,不中断正在处理的请求,SpringBoot 2.3+ 官方正式特性。
二、Docker 容器启动参数
最终 JAVA_OPTS
1 | |
逐条解析
1 | |
让 JVM 识别 Docker 容器内存限制,不读宿主机内存(容器最重要)
1 | |
初始堆 = 容器内存的 50%
最大堆 = 容器内存的 75%
容器内不要用 -Xms -Xmx,用百分比最安全
三、最关键区别(一定要记住)
宿主机
1 | |
固定大小
容器
1 | |
自动适配容器内存,不会 OOM 被系统杀死
七、一句话速记
内存参数控制堆 + 分代 + 元空间;
GC 参数选择收集器 + 停顿限制;
调优核心:少 GC、短停顿、无 FullGC、防 OOM;
流程:监控→分析→改参→压测。