一、先搞懂:JVM 调优调的是什么?
JVM 调优的核心目标:
减少 Full GC 次数(Full GC 会暂停所有业务线程,导致系统卡顿);
控制 Young GC 频率和耗时(Young GC 轻量,但太频繁也会影响性能);
避免内存泄漏 / 溢出(OOM);
提升内存利用率(既不浪费内存,也不频繁回收)。
调优的本质:合理分配堆内存各区域大小 + 选择合适的垃圾收集器 + 监控并优化内存使用。
二、JVM 调优前置:必须懂的内存模型(极简版)
不用记复杂结构,核心记住堆内存的划分:
堆内存(Heap)
├── 年轻代(Young Generation) 占堆的 1/3 ~ 1/2
│ ├── Eden 区(伊甸园):新对象诞生地(占年轻代 80%)
│ ├── Survivor 0(S0):存活对象临时区
│ └── Survivor 1(S1):和 S0 互换使用
└── 老年代(Old Generation) 占堆的 1/2 ~ 2/3
└── 存放存活时间长的对象(年轻代熬过来的)
Young GC:Eden 满了触发,回收年轻代,存活对象移到 Survivor / 老年代;
Full GC:老年代满了触发,回收整个堆(年轻代 + 老年代),性能开销极大。
三、JVM 调优三步法(新手也能落地)
第一步:监控(先找问题,再调优!)
调优不是瞎改参数,先通过工具定位问题:
-
基础工具(JDK 自带,无需安装)
image.png
2.企业级工具
Arthas(阿里开源):线上排查神器,一键查看 GC、内存、线程;
Prometheus + Grafana:长期监控 JVM 指标(GC 次数、内存使用率)。
image.png
新手避坑:别用 CMS(老年代收集器,已废弃)、Serial GC(单线程,性能差)。
第三步:调整核心参数(实战!)
参数不用多,记住核心 8 个就够,以下是 G1GC 调优模板(微服务通用):
# 1. 堆内存大小(必设,固定值,避免JVM自动调整)
-Xms4g # 初始堆内存(和-Xmx一致,避免内存扩容卡顿)
-Xmx4g # 最大堆内存(根据服务器内存设置,如8G服务器设4g)
# 2. 年轻代比例(G1GC 推荐)
-XX:G1NewSizePercent=20 # 年轻代最小占比
-XX:G1MaxNewSizePercent=50 # 年轻代最大占比
# 3. GC 停顿时间目标(G1GC 核心)
-XX:MaxGCPauseMillis=200 # 目标停顿时间(200ms,可根据业务调整)
# 4. 老年代占比阈值(触发混合回收)
-XX:InitiatingHeapOccupancyPercent=45 # 堆内存占45%时触发老年代回收
# 5. 日志配置(必加!排查问题用)
-Xlog:gc*:file=gc.log:time,level,tags # JDK 11+ 日志格式
# JDK 8 替代:-XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xloggc:gc.log
# 6. 其他优化
-XX:+HeapDumpOnOutOfMemoryError # OOM 时自动导出堆快照
-XX:HeapDumpPath=/tmp/heap.hprof # 快照保存路径
-XX:+UseG1GC # 指定 G1GC(JDK 11+ 默认)
四、企业级调优实战案例(从问题到解决)
问题场景:
微服务接口偶尔卡顿,查看 GC 日志发现Full GC 频繁(每小时 10 次),Young GC 也很频繁(每分钟 5 次)。
排查步骤:
用 jstat -gc 进程ID 查看:
Eden 区很小(仅 512M),导致 Young GC 频繁;
老年代占比快速上涨,触发 Full GC。
用 jmap -histo 进程ID 查看:
发现大量字符串对象未释放(可能是内存泄漏)。
五、新手调优避坑指南
别盲目调大堆内存:比如 8G 服务器设 - Xmx8g,会导致 Full GC 耗时更长(一次 Full GC 可能卡 10 秒);
别乱加参数:比如 -XX:+UseConcMarkSweepGC(CMS 已废弃),反而出问题;
调优后一定要监控:改完参数后,观察 1-2 天 GC 日志,确认效果;
优先优化代码:内存泄漏、大对象创建(如一次性加载 10 万条数据),比调参数更有效。
六、通用调优模板(直接复制用)
#1. 微服务(JDK 11+,G1GC)
java -jar \
-Xms4g \
-Xmx4g \
-XX:G1NewSizePercent=20 \
-XX:G1MaxNewSizePercent=50 \
-XX:MaxGCPauseMillis=200 \
-XX:InitiatingHeapOccupancyPercent=45 \
-XX:+HeapDumpOnOutOfMemoryError \
-XX:HeapDumpPath=/tmp/heap.hprof \
-Xlog:gc*:file=gc.log:time,level,tags \
your-app.jar
#2. 单机应用(JDK 8,Parallel GC)
java -jar \
-Xms2g \
-Xmx2g \
-XX:NewRatio=2 \ # 年轻代:老年代 = 1:2
-XX:SurvivorRatio=8 \ # Eden:S0:S1 = 8:1:1
-XX:+PrintGCDetails \
-XX:+PrintGCTimeStamps \
-Xloggc:gc.log \
-XX:+HeapDumpOnOutOfMemoryError \
your-app.jar
七、其他工具
Arthas 阿尔萨斯
jvisualvm(VisualVM) 是 JDK 自带的图形化 JVM 监控与分析工具,能直观看到 CPU、堆内存、新生代 / 老年代、GC、线程、类加载 的实时曲线,完全图形化,不用记命令。

核心图形化面板(对应你关心的内存 / GC)
CPU:实时 CPU 使用率曲线
堆内存 Heap:总大小、已使用、空闲 → 看是否持续上涨(泄漏)
类加载:加载类数量
线程:活动线程数
-
按钮:
- Perform GC:手动触发 Full GC(测试回收效果)
- Heap Dump:生成堆快照(排查 OOM / 泄漏)
Visual GC:
Eden:新生代 Eden 区曲线(对象创建区)
S0/S1:Survivor 区
Old:老年代(你关心的 FullGC 区)
Metaspace:元空间
GC Time:Minor GC / Full GC 耗时、次数
一眼判断:
Eden 涨太快 → 对象创建过多
Old 持续涨、FullGC 后不下降 → 内存泄漏
FullGC 频繁、耗时高 → 性能瓶颈
「线程(Threads)」图形
线程状态图:运行、休眠、等待、阻塞
线程数曲线:是否无限增长(线程泄漏)
死锁自动标红:直接看到死锁线程
「采样器(Sampler)」(定位热点)
CPU 采样:图形化看哪个方法最耗 CPU
内存采样:哪个类创建对象最多、占用最大(定位你说的 new 过多)

