Java 生产环境 JVM 调优实战
目录一、生产 JVM 调优前置知识必须掌握1. 核心调优指标生产看这 4 个就够2. 必备监控工具生产标配3. 核心 JVM 参数生产常用无废话二、标准生产调优流程固定 5 步三、4 个生产最典型的 JVM 调优实战案例案例 1YGC 频繁但单次停顿短高频小对象场景场景描述根因调优方案效果案例 2频繁 FullGC服务卡顿、超时最危险场景场景描述常见根因排查步骤调优方案效果案例 3大对象导致频繁 YGCFGC文件 / 图片 / 报文处理场景描述根因调优方案效果案例 4G1GC 调优JDK11 微服务通用场景场景描述根因调优方案效果四、生产 JVM 参数最佳实践模板直接复制用1. JDK8 低延迟服务支付 / 电商2. JDK11 微服务通用最优五、避坑指南生产 90% 的人踩过总结JVM 调优核心目标降低 GC 频率 / 停顿时间、避免 OOM、提升吞吐量、保证服务稳定。生产环境调优一定遵循监控定位 → 分析问题 → 参数调整 → 验证效果闭环绝不盲目加参数。本文会用生产真实场景从基础流程到 4 个典型实战案例手把手讲透。一、生产 JVM 调优前置知识必须掌握1. 核心调优指标生产看这 4 个就够GC 停顿时间STW越短越好电商 / 支付 200ms日志 / 批处理可放宽GC 频率YGC 尽量频繁但快FGC/FullGC越少越好最好 0内存使用率老年代不持续上涨、无内存泄漏吞吐量用户代码执行时间 /(用户代码 GC 时间)越高越好2. 必备监控工具生产标配实时查看jstat -gc PID 1000 10最常用看 GC 次数 / 耗时内存 dumpjmap -dump:formatb,fileheap.hprof PIDOOM 必用日志分析开启-XX:PrintGCDetailsGC 日志用GCViewer/GCEasy分析可视化Arthas阿里开源生产首选无侵入、PrometheusGrafana3. 核心 JVM 参数生产常用无废话# 基础内存配置必配 -Xms4g # 初始堆 最大堆避免扩容停顿生产强制相等 -Xmx4g # 最大堆 -Xss1024k # 线程栈大小默认1M足够递归深可调大 -XX:MetaspaceSize256m -XX:MaxMetaspaceSize512m # GC算法生产主流JDK8用CMSJDK11用G1ZGC -XX:UseConcMarkSweepGC # JDK8 低延迟首选 -XX:UseG1GC # JDK11 默认平衡吞吐量/延迟 # GC日志生产必须开启排查问题救命用 -Xloggc:/logs/gc.log -XX:PrintGCDetails -XX:PrintGCDateStamps -XX:UseGCLogFileRotation -XX:GCLogFileSize100M # 异常保护必配 -XX:HeapDumpOnOutOfMemoryError # OOM自动dump内存快照 -XX:HeapDumpPath/logs/heap.hprof二、标准生产调优流程固定 5 步监控发现问题YGC 频繁、FGC 不断、CPU 高、OOM分析根因内存泄漏对象创建太快堆太小老年代囤积调整参数只改 1-2 个参数不一次性堆参数压测 / 观察观察 GC 指标变化固化最优配置稳定后保留参数写入 Docker/K8s 启动脚本三、4 个生产最典型的 JVM 调优实战案例案例 1YGC 频繁但单次停顿短高频小对象场景场景描述微服务接口 QPS 高大量创建局部对象DTO、List、Mapjstat显示YGC 每 1-2 秒一次每次 10msFGC 0服务无卡顿但 GC 消耗 CPU 资源根因新生代EdenS 区太小对象快速占满 Eden触发频繁 YGC。调优方案增大新生代空间降低 YGC 频率# 原配置 -Xms2g -Xmx2g # 调优后新生代占堆 1/2默认是 1/3 -Xms2g -Xmx2g -Xmn1g效果YGC 频率从1 次 / 秒 → 1 次 / 10 秒GC CPU 使用率下降服务更稳定。案例 2频繁 FullGC服务卡顿、超时最危险场景场景描述订单 / 支付核心服务突然接口大量超时jstat显示FGC 几分钟一次不断增长单次停顿 500ms堆内存老年代持续 100% 占用常见根因内存泄漏连接未关闭、静态集合缓存对象对象直接进入老年代大对象 / 动态晋升老年代空间不足排查步骤导出堆 dumpjmap -dump:formatb,fileoom.hprof PID用 MAT 工具分析发现静态 Map 缓存了大量订单对象未清理→ 内存泄漏调优方案代码修复给缓存加过期时间、使用弱引用 / 本地缓存框架CaffeineJVM 参数辅助# 增大堆调整CMS触发阈值提前回收 -Xms4g -Xmx4g -XX:UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction70 # 老年代占70%触发CMS避免满了再GC -XX:UseCMSInitiatingOccupancyOnly效果FGC 降为0 / 天GC 停顿 100ms服务无卡顿。案例 3大对象导致频繁 YGCFGC文件 / 图片 / 报文处理场景描述服务处理 Excel 导入、大报文解析创建几 MB 的大对象JVM 报错Preventing promotion of large objectYGC 和 FGC 同时频繁OOM 频发根因大对象直接进入老年代Eden 放不下老年代快速被占满。调优方案代码优化拆分大对象流式处理不一次性加载全量数据JVM 参数# 1. 调大大对象阈值让大对象优先在新生代分配 -XX:PretenureSizeThreshold10m # 10M才直接进老年代 # 2. 增大新生代 -Xms4g -Xmx4g -Xmn2g效果大对象不再直接进入老年代FGC 消失OOM 解决。案例 4G1GC 调优JDK11 微服务通用场景场景描述SpringCloud 微服务JDK11默认 G1GC偶尔出现GC 停顿超过 300ms接口超时堆内存 4G无内存泄漏根因G1 默认目标停顿200ms未根据业务调整混合回收效率低。调优方案G1 调优只改一个核心参数期望停顿时间-Xms4g -Xmx4g -XX:UseG1GC -XX:MaxGCPauseMillis100 # 目标停顿100msG1自动调整分区大小 -XX:ConcGCThreads4 # 根据CPU核心数调整效果GC 平均停顿 **80ms**无明显波动服务稳定。四、生产 JVM 参数最佳实践模板直接复制用1. JDK8 低延迟服务支付 / 电商JAVA_OPTS -Xms4g -Xmx4g -Xmn2g -XX:MetaspaceSize256m -XX:MaxMetaspaceSize512m -XX:UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction70 -XX:UseCMSInitiatingOccupancyOnly -Xloggc:/logs/gc.log -XX:PrintGCDetails -XX:PrintGCDateStamps -XX:HeapDumpOnOutOfMemoryError -XX:HeapDumpPath/logs/ 2. JDK11 微服务通用最优JAVA_OPTS -Xms4g -Xmx4g -XX:UseG1GC -XX:MaxGCPauseMillis100 -XX:MetaspaceSize256m -XX:MaxMetaspaceSize512m -Xlog:gc*:/logs/gc.log:time,level,tags -XX:HeapDumpOnOutOfMemoryError -XX:HeapDumpPath/logs/ 五、避坑指南生产 90% 的人踩过不要堆参数一次只改 1 个参数观察效果-Xms 必须等于 - Xmx避免堆扩容导致的长时间停顿不要无限加大堆堆越大FGC 停顿越长4-8G 最均衡先修代码再调 JVM内存泄漏、大对象靠调优解决不了必须开 GC 日志和 OOM dump出问题能快速定位总结JVM 调优核心先监控定位再小步调整不盲目操作生产高频问题YGC 频繁加新生代、FGC 频繁内存泄漏 / 老年代不足、大对象最优方案代码优化为主JVM 参数为辅配合 GC 日志 Arthas 工具直接可用两套参数模板适配 JDK8/JDK11覆盖绝大多数微服务场景