G1收集器以动态角色可变的Region为回收单位,按需选择高垃圾占比Region进行Mixed GC。Region大小自动计算,避免手动设置过大或过小;Humongous Region专存大对象,RSet与写屏障保障跨区引用追踪,实现低延迟混合回收。

G1收集器的Region划分不是把堆“切块备用”,而是构建一种动态、按需调度的回收单位体系。它用大小相等但物理不连续的Region替代传统新生代/老年代的固定连续分区,让内存管理更灵活、回收更可控。
Region是角色可变的逻辑单元,不是静态分区
每个Region在任意时刻只承担一种角色:Eden、Survivor、Old 或 Humongous。这种角色不是写死的,而是随对象分配和GC过程动态变化。比如某次Young GC后,一个原本是Eden的Region可能变成Survivor;下一次它又可能被选为Old Region来存放晋升对象。Humongous Region则专用于存放≥50% Region大小的大对象,由连续多个Region组成,不参与复制算法,直接标记-清除。
关键点在于:Region之间没有物理连续性要求,也不强制绑定代际边界。这打破了CMS或Parallel GC中“新生代必须连着老年代”的限制,为混合回收打下基础。
回收以Region为最小粒度,优先处理“高价值”区域
G1不整代扫描,而是基于并发标记阶段统计出每个Region的垃圾占比(即“回收价值”)。Mixed GC启动后,它只挑选那些垃圾比例高、且存活对象少的老年代Region加入回收集合(Collection Set),同时一并回收所有Eden和Survivor Region。
这种策略依赖两个支撑机制:
- Remembered Set(RSet):每个Region自带RSet,记录哪些其他Region有指向它的引用。回收时只需检查RSet,无需全堆扫描,大幅降低STW时间。
- Card Table + Write Barrier:当发生跨Region引用写操作时,JVM通过写屏障标记对应卡页(card),后续再异步更新RSet,保证引用关系准确又不拖慢应用线程。
Mixed GC不是“老年代满了就收”,而是一套条件触发的闭环流程
Mixed GC不会单独出现,它必须走完完整的并发标记周期,并满足三个硬性条件才会启动:
- 整个堆的占用率达到-XX:InitiatingHeapOccupancyPercent阈值(默认45%,注意是占总堆比例,不是老年代自身);
- 并发标记已结束;
- 堆中被判定为“无法回收的碎片”超过-XX:G1HeapWastePercent(默认5%)。
一旦触发,G1会分多次执行Mixed GC,每次控制暂停时间(由-XX:MaxGCPauseMillis软目标约束),逐步清理高价值Region,直到老年代空间压力缓解或达到预设回收上限。
Region大小不必手动调优,但要避开常见误区
Region默认大小由JVM根据堆总容量自动计算(目标约2048个Region),范围1MB–32MB且为2的幂。强行指定-XX:G1HeapRegionSize容易适得其反:
- 设太小(如1MB)→ Region数量爆炸 → RSet元数据开销飙升,反而拖慢GC;
- 设太大(如32MB)→ 单Region内对象生命周期差异大 → 回收效率下降,还可能加剧Humongous分配失败风险。
真正需要关注的是对象大小分布:避免频繁分配接近Region一半的大对象,防止Humongous Region堆积或因找不到连续空间而触发Full GC。









