混合回收阶段堆内存碎片化是G1分区机制与对象生命周期不匹配所致:Humongous对象割裂空闲Region、Mixed GC选择性回收形成孤岛、RSet占用空间并干扰回收判断、无压缩导致内外碎片叠加。

混合回收(Mixed GC)阶段堆内存碎片化不是偶然现象,而是G1收集器分区管理机制与对象生命周期分布不匹配共同作用的结果。
Humongous对象强制占用连续Region
G1把堆划分为固定大小的Region,但大对象(≥Region大小50%)必须分配在连续的Humongous Region中。一旦这些Region被分散占用,就无法合并成更大连续空间。频繁创建订单、日志、缓存等大对象时,Humongous Region像“钉子”一样插在堆中,把原本可整合的空闲Region割裂开。
- 一个16MB的Region,只要对象超过8MB,就必须走Humongous路径
- 释放后,这些Region不会立即归还给全局空闲列表,而是标记为“待重用”,但无法参与常规Region合并
- 多个小块Humongous Region残留,直接导致后续大对象分配失败,触发Full GC
Mixed GC只回收部分老年代Region
Mixed GC的目标是“优先回收垃圾最多的Region”,不是“清空所有老年代”。它按收益排序选择若干Region回收,其余存活对象密集的老年代Region被跳过。结果就是:
- 已回收Region变成空闲,但位置零散
- 未回收Region中仍驻留大量存活对象,形成“孤岛”
- 空闲Region之间被这些“孤岛”隔开,无法拼出连续空间
Remembered Set带来隐性空间割裂
每个Region都维护RSet记录跨区引用,这部分元数据占堆内存10%~20%,且不能移动。它虽不直接产生碎片,却造成两个间接影响:
- 实际可用堆空间缩水,放大了碎片感知——明明还有1GB空闲,但因RSet占位和分布离散,无法满足512MB连续申请
- RSet更新本身需写屏障开销,在并发阶段可能延迟Region状态同步,使Mixed GC误判某些Region“仍有强引用”,从而跳过本可回收的区域
没有压缩动作加剧外部碎片固化
G1默认不移动对象(除Full GC外),Mixed GC只是清空选中的Region,不整理剩余Region内的存活对象。这意味着:
- 老年代Region内部可能出现“存活-空洞-存活”交错布局
- 这些内部空洞无法被其他Region复用,只能等待该Region整块回收
- 长期运行后,外部碎片(空闲Region不连续)和内部碎片(单Region内空洞)叠加,形成双重碎片死结

















