增量收集与并发收集的核心目标是将长停顿拆分为多次短停顿并让GC线程与用户线程尽可能并行,关键在于控制用户线程阻塞时间与单位时间有效回收量的比例;G1通过Region化、增量回收与并发标记实现较优平衡,需合理配置-XX:MaxGCPauseMillis和-XX:ConcGCThreads,并关注应用对象生命周期行为对效果的实际影响。

增量收集与并发收集的核心目标,不是消除停顿,而是把原本一次长停顿,拆成多次短停顿,并尽可能让垃圾回收线程与用户线程同时运行——关键在于控制“用户线程被阻塞的时间”和“单位时间完成的有效回收量”之间的比例。
用增量收集降低单次停顿峰值
增量收集(Incremental Collection)把一次完整的GC过程切分为多个小步,在用户线程运行间隙穿插执行。例如:CMS 的初始标记和重新标记阶段虽需 STW,但耗时极短;而并发标记、并发清除则完全与应用线程并行。
- 适用场景:对最大停顿时间敏感(如实时交互类服务),但能容忍略低的吞吐量
- 关键配置:通过 -XX:MaxGCPauseMillis(G1/CMS)设定目标停顿上限,JVM 会自动调整工作量分片大小
- 注意点:频繁的微停顿可能引发上下文切换开销,实际停顿总和未必小于一次完整 GC
靠并发收集提升整体吞吐效率
并发收集(Concurrent Collection)让 GC 线程与用户线程重叠运行,典型代表是 CMS 和 G1 的并发标记阶段。它不追求零停顿,而是把 STW 控制在可预测、可接受范围内,同时释放更多 CPU 时间给业务逻辑。
- 优势:大幅减少 STW 总时长,尤其适合多核服务器和中大堆内存(4GB+)
- 代价:需要额外内存空间(如 CMS 的预留空间、G1 的 Remembered Set 维护开销)和 CPU 资源用于并发追踪
- 调优重点:确保并发线程数合理(-XX:ConcGCThreads),避免抢占过多 CPU 导致应用响应变慢
G1 是目前最实用的平衡方案
G1 将堆划分为多个 Region,支持增量式回收(每次只清理部分 Region)和并发标记。它既不像 CMS 那样容易失败导致 Full GC,也不像 Parallel GC 那样停顿不可控。
- 设置预期停顿目标:-XX:MaxGCPauseMillis=200(默认 200ms),JVM 自动选择要回收的 Region 数量
- 避免过度并发:若观察到 GC 线程长期占用 CPU,可适当调低 -XX:ConcGCThreads(建议设为 CPU 核数的 1/4)
- 监控依据:重点关注 G1 Evacuation Pause(STW)和 G1 Concurrent Cycle(并发阶段)的耗时分布,而非仅看 GC 频率
真正影响平衡效果的往往是应用行为
算法再先进,也受限于对象生命周期分布和分配速率。突发性大对象分配、过早晋升、长时间持有老年代引用,都会打破增量/并发设计的理想假设。
- 检查对象年龄:用 -XX:+PrintGCDetails -XX:+PrintTenuringDistribution 观察幸存区晋升规律
- 减少跨代引用:避免在老年代对象中长期缓存新生代对象(如静态 Map 持有局部对象)
- 控制分配节奏:对高频短生命周期对象,优先复用对象池或使用栈上分配(Escape Analysis 启用后自动优化)










