Mixed GC是STW的复制式回收,只处理年轻代全部Region和老年代中收益高的候选Region;触发需同时满足堆使用率≥IHOP阈值且上一轮并发标记已完整结束;回收范围受存活率、巨型对象、RSet就绪状态限制;执行分初始标记、Evacuation、RSet更新三步;轮数默认最多8轮,动态调节每轮回收的老年代Region数量。

Mixed GC 回收年轻代和部分老年代,不是简单“一起扫一遍”,而是有明确分工、严格条件和动态筛选机制。它本质是一次 STW 的复制式回收,但只处理“值得收”的区域。
触发前提:两个硬性条件必须同时满足
仅堆用得多或老年代满得早都不够:
- 堆总使用率 ≥ IHOP 阈值(默认 45%,由 -XX:InitiatingHeapOccupancyPercent 控制)——这是启动并发标记的开关;
- 上一轮全局并发标记周期已完整结束(含初始标记、并发标记、最终标记、清理阶段),且清理阶段已产出一批可回收的老年代 Region 列表。
缺一不可。比如堆已用 52%,但并发标记中途被取消(日志出现 Concurrent Cycle was cancelled),Mixed GC 就不会发生;反过来,老年代占了 90%,但总堆才用 38%,根本没触发标记,也不会进入 Mixed GC。
回收范围:年轻代全收 + 老年代按收益精选
年轻代部分是确定项,所有 Eden 和 Survivor Region 都参与;老年代部分则是动态挑选的子集:
立即学习“Java免费学习笔记(深入)”;
- 必收:全部 Eden Region、当前存活的 Survivor Region;
- 选收:从并发标记产出的候选老年代 Region 中,过滤并排序后挑出若干个;
- 跳过不收的 Region:存活率超过 -XX:G1MixedGCLiveThresholdPercent(默认 85%)、巨型对象(Humongous)Region、Remembered Set 尚未就绪(跨 Region 引用未完全记录)的 Region。
真正决定收哪些老年代 Region 的,是“单位时间回收收益”:优先选垃圾占比高、复制存活对象成本低的 Region,也就是腾空间多、搬得快的。
执行过程:STW 下分步完成 Evacuation
Mixed GC 全程 STW,但受 -XX:MaxGCPauseMillis 约束,必须在目标停顿时间内完成。关键步骤包括:
- 初始标记(STW):标记 GC Roots 直接可达对象,并扫描 Survivor 区引用的老年代对象(Root Region Scanning);
- Evacuation(STW 核心阶段):将 Eden 中存活对象复制到 Survivor 或老年代;将 Survivor 中年龄达标或空间不足的对象晋升至老年代;同时把选定的老年代 Region 中的存活对象复制到其他空闲 Region(可能是 Survivor 或老年代);
- Remembered Set 更新:同步刷新跨 Region 引用记录,确保下次 GC 能准确定位外部引用。
整个过程不整理整个老年代,也不清空所有老年代 Region,只对入选的 Region 做复制+整理,因此不会退化为 Full GC。
回收节奏:受历史表现与压力共同调节
本轮收多少个老年代 Region,不是固定数量,而是由三方面动态平衡:
- 历史回收误差:上次预测是否偏高/偏低,影响本次估算精度;
- 当前老年代压力:剩余空闲 Region 数量越少,越倾向多收几个;
- 全局轮数目标:默认最多执行 8 轮 Mixed GC(由 -XX:G1MixedGCCountTarget 控制),每轮逐步回收一部分,避免单次压力过大。
如果 Mixed GC 持续跟不上内存分配速度,老年代填满且无空闲 Region 可用,才会被迫降级为 Serial Old(Full GC)。


















