cset是g1每次gc暂停时动态选取的待回收region集合,所有region均被清空,存活对象复制迁移;年轻代gc仅含eden/survivor region,混合gc则额外加入垃圾率高、rset引用少、迁移成本低的老年代region。

G1收集器中CSet(Collection Set)不是固定划分的区域集合,而是每次GC前动态计算、按需选取的一组Region。它的核心逻辑是:**优先把垃圾最多、回收收益最高、清理成本最低的Region纳入本次回收范围**,从而在有限停顿时间内达成最大内存释放效果。
什么是CSet及其作用
CSet是G1执行一次Evacuation(疏散)暂停时实际处理的Region集合。所有CSet中的Region都会被清空——存活对象复制到其他空闲Region,原Region则被释放为可用空间。它不区分“必须回收”或“强制保留”,只服务于当前GC目标:用最短时间腾出最多内存。
年轻代GC的CSet仅含Eden和Survivor Region;混合GC的CSet则同时包含部分Eden/Survivor Region和若干老年代Region,后者由并发标记阶段产出的回收价值评估结果决定。
垃圾收益怎么算:三个关键维度
G1对每个候选Region计算“回收收益”,主要依据以下三项指标综合加权:
- 垃圾占比(Garbage Ratio):Region中已死亡对象占用的空间比例。越高越好,例如90%垃圾的Region比30%的优先级高得多;
- 跨Region引用强度(RSet扫描开销):该Region被其他Region通过RSet记录的引用数量越少,说明并发标记后需检查的外部依赖越轻,疏散时STW时间越可控;
- 存活对象迁移成本:Region中存活对象总大小越小、分布越紧凑,复制所需CPU和内存带宽越低,更适合放入CSet。
动态选择过程如何运作
CSet构建发生在混合GC触发前,依赖前期并发标记周期输出的数据:
- 并发标记结束后,G1统计每个Old Region的存活率(Live Ratio),默认只考虑存活率低于85%(即垃圾率>15%)的Region作为混合回收候选(由
-XX:G1MixedGCLiveThresholdPercent控制); - 再按垃圾率从高到低排序,结合
-XX:MaxGCPauseMillis设定的目标停顿时间,预估本轮能安全处理多少Region——例如目标200ms,估算每个Region疏散耗时15ms,则最多选13个; - 最终CSet大小还受
-XX:G1OldCSetRegionThresholdPercent限制(默认10%),即老年代Region总数的10%为上限,防止某次混合GC过度侵入老年代影响吞吐。
为什么这个机制能兼顾低延迟与高效率
传统收集器如CMS整代回收,不管某块老年代区域是否“值得动”,容易造成资源浪费或漏掉高收益区域;G1的CSet机制相当于给每块内存贴上“性价比标签”,让GC线程始终聚焦在“投入产出比最高”的局部战场。既避免了Full GC式的全局扫描,又不像纯年轻代回收那样对老年代放任不管——真正实现了按需治理、精准打击。











