g1的mixed gc是一次stw的复制式回收,以young gc为入口,按收益比动态选择老年代region加入回收集,需同时满足并发标记完成和堆占用超ihop阈值两个前提,多轮渐进执行后自动退出。

G1 的 Mixed GC 不是“同时发起两套回收逻辑”,而是以一次 Young GC 为入口,在满足特定前提后,把部分老年代 Region 主动加入当前回收集(CSet),统一用 Evacuation(疏散)方式处理——年轻代 Region 全收,老年代 Region 按需选收,整个过程仍是一次 STW 的复制式回收。
触发 Mixed GC 的两个硬性前提
Mixed GC 不会独立启动,它依赖并发标记周期完成 + 堆占用越过 IHOP 阈值这两个条件同时成立:
- 堆总使用率 ≥ -XX:InitiatingHeapOccupancyPercent(默认 45%),这是启动并发标记的开关;
- 并发标记周期已完整走完:包括初始标记(Initial Mark)、并发标记(Concurrent Mark)、最终标记(Remark)和清理(Cleanup)阶段,且 Cleanup 阶段已产出一批“垃圾占比高、可安全回收”的老年代 Region 列表。
缺一不可。比如堆用了 50%,但并发标记被取消(日志出现 Concurrent Cycle was cancelled),就不会进入 Mixed GC;反过来,老年代占了 90%,但总堆才用 30%,根本没触发标记,也不会来 Mixed GC。
回收哪些老年代 Region:按“收益比”动态筛选
G1 不按顺序扫老年代,而是从 Cleanup 输出的候选集中,按实际回收价值排序挑选:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 跳过不合适的 Region:存活率超过 -XX:G1MixedGCLiveThresholdPercent(默认 85%)的、巨型对象(Humongous)Region、Remembered Set(RSet)尚未就绪的 Region 都会被跳过;
- 优先选“高垃圾占比 + 低复制成本”的 Region:比如一个 Region 垃圾占 70%、存活对象少且小,移动快,就比一个垃圾只占 40% 但要搬运大量大对象的 Region 更优;
- 数量受三重调节:历史回收误差(预测是否偏高)、当前老年代空闲 Region 数量、以及本轮 Mixed GC 的轮数目标(-XX:G1MixedGCCountTarget,JDK8u40+ 默认最多 8 轮)共同决定本次收几个。
执行过程:一次 STW,统一疏散,分区域处理
Mixed GC 是一次 Stop-The-World 操作,但所有工作都在用户设定的停顿目标(-XX:MaxGCPauseMillis)内完成:
- 根扫描阶段:同时检查 GC Roots 和所有 RSet,确保跨 Region 引用不遗漏;
- Evacuation 阶段:将 Eden 所有 Region、部分 Survivor Region,以及选定的老年代 Region 中的存活对象,统一疏散到新的空闲 Region;
- 晋升规则不变:年龄未达阈值的进 Survivor,达阈值或空间不足则直接晋升至老年代 Region;
- 原 Region 清空后归入空闲列表,后续可重新分配为 Eden/Survivor/Old 角色。
整个过程复用 Young GC 的疏散代码,只是回收集扩展了老年代 Region —— 所以它不是“两套流程并行”,而是一套流程覆盖更多区域。
多轮渐进与退出机制
Mixed GC 是一组连续动作,不是一次性清空老年代:
- 默认最多执行 G1MixedGCCountTarget 轮(如 8 轮),每轮回收一部分老年代 Region;
- 每轮结束后重新评估剩余老年代 Region 的垃圾比例,动态调整下一轮回收集;
- 当待回收老年代 Region 总量低于 -XX:G1HeapWastePercent(默认 5%),或回收效率持续下降,G1 自动终止 Mixed GC 序列,回归纯 Young GC;
- 若老年代晋升太快、并发标记跟不上,导致空闲 Region 耗尽,可能退化为 Full GC —— 这是需要规避的异常路径。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










