jvm调优核心是从业务场景出发确定目标:交易类系统优先低延迟(p99≤100ms、full gc≥24小时一次),批处理类优先高吞吐量(工作线程占比≥98%),内存受限环境优先控内存占用(老年代使用率≤70%);必须监控gc行为、堆使用率、停顿时间分布及非堆内存四大指标,三者构成“不可能三角”,需根据实际数据取舍平衡。

确定 JVM 调优的优化目标和指标,核心是**从业务场景出发,不凭感觉、不套模板**。不是所有应用都需要调优,也不是所有指标都要“越高越好”。关键在于识别系统瓶颈与业务诉求的匹配关系。
先看业务类型决定主攻方向
不同系统对性能的敏感点完全不同:
- 交易类系统(如支付、下单):用户感知强,优先保 低延迟 —— STW 时间要短(目标通常 ≤ 200ms),P99 响应时间稳定,Full GC 频次极低(如 ≥ 24 小时一次)
- 批处理/离线计算类(如报表生成、ETL):无人实时交互,优先保 高吞吐量 —— 关注单位时间完成任务数,可接受稍长但稳定的 GC 暂停,目标是让工作线程运行时间占比 ≥ 98%
- 内存受限环境(如容器化部署、边缘服务):堆空间有限,优先控 内存占用 —— 老年代使用率长期 ≤ 70%,避免频繁扩容和内存抖动,Metaspace 和 Direct Memory 也要纳入监控
必须盯紧的四大基础指标
这些不是“可选”,而是调优前后的必查项,缺一不可:
- GC 行为指标:Full GC 次数/小时、单次 Full GC 耗时、Young GC 频率、GC 后老年代剩余空间变化趋势(是否持续上涨)
- 堆内存使用率:老年代使用率(>90% 是危险信号)、Eden 区回收后存活对象比例(若长期 >15%,说明对象过早晋升)
- 停顿时间分布:不只是平均值,更要关注 P90/P99 停顿 —— 一次 2 秒的卡顿比十次 200ms 更致命
- 非堆内存异常:Metaspace OOM、DirectMemory OOM、线程数暴涨(-Xss 设置不当或线程泄漏)
用数据代替猜测,拒绝“我觉得”
目标不能靠拍脑袋定,必须基于真实运行数据:
- 上线前做基线采集:用 -Xlog:gc*:file=gc.log:time,tags,uptime 开启详细 GC 日志,跑 24 小时常规流量
- 压测中抓关键窗口:比如大促模拟时,每 5 分钟采样一次 jstat -gc 输出,观察老年代增长斜率和 GC 触发节奏
- 对比业务指标联动分析:响应时间突增时,是否同步出现 Full GC?错误率上升是否伴随 Metaspace 使用率达 99%?
记住那个“不可能三角”
吞吐量、延迟、内存占用三者无法同时最优。调优本质是取舍:
- 想降延迟?可能得加堆内存(牺牲内存占用),或换 G1/ZGC(但需 JDK 版本支持)
- 想提吞吐?Parallel GC 更合适,但单次停顿会变长,不适合交互型服务
- 想省内存?缩小堆可能导致 GC 更频繁,反而拖慢吞吐、抬高延迟
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











