核心思路是优化新生代配置以减少Full GC:合理设置新生代大小、Survivor区比例、对象晋升阈值及回收器,结合业务特征精细调参。

核心思路是让多数对象在新生代内完成创建与回收,避免过早晋升到老年代,从而大幅减少 Full GC 次数和系统卡顿。
合理设置新生代大小
新生代太小会导致 Minor GC 频繁,停顿虽短但累积开销大;太大则单次 GC 时间变长,且可能挤占老年代空间,反而诱发 Full GC。
- 用 -Xms 和 -Xmx 固定堆总大小(如
-Xms4g -Xmx4g),避免运行时扩容抖动 - 通过 -XX:NewRatio 控制新生代占比(如
-XX:NewRatio=2表示新生代:老年代 = 1:2) - 更精细控制可用 -XX:NewSize 和 -XX:MaxNewSize(如
-XX:NewSize=1g -XX:MaxNewSize=1g) - 对高并发短生命周期对象场景(如电商订单系统),新生代建议占堆内存的 1/3~1/2
优化 Survivor 区配置
Survivor 区太小,对象容易因“放不下”而直接晋升老年代;太大又浪费空间,且延长复制成本。
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
- 用 -XX:SurvivorRatio 调整 Eden 与 Survivor 比例(默认 8,即 Eden:S0:S1 = 8:1:1)
- 若观察到 GC 日志中 “
Desired survivor size” 常被突破,或晋升量突增,说明 Survivor 不足,可调小该值(如设为 4,使 Survivor 占比升至 20%) - 配合 -XX:+PrintGCDetails 查看每次 Minor GC 后存活对象大小,验证 Survivor 是否够用
控制对象晋升行为
多数短命对象不该进入老年代——这是调优的关键落点。
- 用 -XX:MaxTenuringThreshold 限制晋升年龄(默认 15,可结合业务设为 4~6,避免长期滞留 Survivor)
- 启用 -XX:+AlwaysTenure(慎用)可跳过 Survivor 直接晋升,仅适用于已知必然长存的对象
- 对大对象(如大数组、缓存块),用 -XX:PretenureSizeThreshold 设阈值(如
-XX:PretenureSizeThreshold=1048576即 1MB),使其直接进老年代,避开新生代压力
选对新生代回收器并调优线程数
回收器类型和并发能力直接影响吞吐与延迟。
- 多核服务器优先用 ParNew(
-XX:+UseParNewGC)或 G1(-XX:+UseG1GC),避免单线程 Serial - ParNew 默认线程数 = CPU 核数;若 GC 线程过多导致上下文切换开销,可用 -XX:ParallelGCThreads 手动限制(如 8 核设为 6)
- G1 更适合大堆(≥4GB),用 -XX:MaxGCPauseMillis 设目标停顿(如 200ms),JVM 自动调节区域回收节奏


















