分代收集的核心思想是利用对象“朝生夕灭”的统计规律,将堆划分为新生代和老年代,分别采用Minor GC(复制算法、快而高频)和Major GC(标记-清除/整理、慢而低频)协同回收,以优化吞吐量与延迟;关键权衡在于控制对象晋升节奏,避免过早填满老年代。

分代收集的核心思想,是利用对象“朝生夕灭”的统计规律,把堆划成新生代和老年代,再用不同策略回收——这不是为了理论漂亮,而是实打实的性能取舍。Minor GC快、轻、高频;Major GC(即老年代回收)慢、重、低频。两者不是并列选项,而是一套协同机制:Minor GC干得越高效,越能延缓Major GC的到来。
Minor GC:速度优先的设计
它只扫新生代(Eden + Survivor),默认用复制算法:活着的对象被集中拷贝到另一个Survivor区或直接晋升,死亡对象原地清空,不产生碎片。这带来三个关键优势:
- 停顿极短:通常5–50ms,多数应用几乎无感
- 吞吐压力小:只处理短期对象,存活率常低于10%,90%以上空间一扫即空
- 可预测性强:触发条件明确(Eden满),容易通过-Xmn、-XX:SurvivorRatio等参数调优
Major GC:代价高昂的兜底动作
它针对老年代,采用标记-清除或标记-整理算法。对象多、存活率高、内存布局松散,导致它天然比Minor GC慢得多:
- STW时间长:常达100ms–1s以上,对延迟敏感服务是明显瓶颈
- 易引发连锁反应:一次Major GC失败(如晋升失败),往往立刻触发Full GC
- 碎片风险真实存在:标记-清除后可能留下大量不连续空闲块,影响大对象分配
真正的权衡点在“晋升控制”
Minor GC本身不危险,危险的是它把太多对象过早、过量地推给老年代。以下情况会加速Major GC到来:
- Survivor区太小(-XX:SurvivorRatio设得过大),导致对象“活一轮就升”
- MaxTenuringThreshold设得太低(比如调成3),短命对象也被提前送进老年代
- 大对象绕过新生代(-XX:PretenureSizeThreshold设置不当),直接占老年代空间
- 每次Minor GC后存活对象激增(比如缓存滥用、日志对象堆积),快速填满Survivor并溢出晋升
现代收集器正在模糊这条线
G1不再严格区分Minor/Major,而是按Region混合回收;ZGC、Shenandoah全程并发,基本消除了传统Major GC的STW痛点。但理解分代权衡仍有价值——它帮你读懂GC日志、定位晋升异常、判断是否该换收集器,而不是盲目调大堆内存。


















