cms与g1碎片处理的根本差异在于碎片是否立即阻断分配:cms因标记-清除+连续老年代,碎片即导致分配失败;g1通过region化+标记-整理,使碎片局限于单region内,不阻碍跨region分配。

CMS 和 G1 在碎片化处理上的根本差异,不在“是否产生碎片”,而在于“碎片是否立即阻断内存分配”——前者因算法和结构设计,碎片即失效;后者通过区域化与整理机制,让碎片不直接拦路。
算法底层:标记-清除 vs 标记-整理
CMS 使用标记-清除算法:只清除垃圾对象,不移动存活对象。老年代是一整块连续空间,空闲内存呈离散小块。当需要分配大对象(如数组、缓存块),必须找到一块连续空闲区域;一旦找不到,哪怕总空闲量充足,也会触发 promotion failure 或 concurrent mode failure,最终退化为 Serial Old 全堆压缩式 GC。
G1 采用标记-整理(局部复制)策略:在筛选回收阶段,它把选中的 Region 中的存活对象复制到其他 Region,原 Region 整体释放。这天然完成空间整理,避免了 CMS 那种“有空却用不上”的假性耗尽。
内存组织:连续段 vs 固定大小 Region
CMS 的老年代是单一连续内存段,碎片随长期运行不断累积,越用越碎,无法隔离或绕过。
G1 将堆划分为固定大小(默认 1–32MB)的独立 Region。分配对象时,只要存在一个空闲 Region(或多个 Region 拼凑满足需求),就能完成分配。它不依赖某一段连续地址空间——碎片被约束在单个 Region 内部,不影响跨 Region 分配。即使某些 Region 剩余少量空间,只要整体空闲 Region 数量足够,分配就不会失败。
应对机制:被动压缩 vs 主动收益驱动回收
CMS 对碎片无日常治理能力。只有等到发生 Concurrent Mode Failure 或 Full GC 时,才可能借助 UseCMSCompactAtFullCollection 开关触发一次压缩,但这是高停顿的补救动作,且仅限 Full GC 场景。
G1 的 Mixed GC 本身就是整理过程:它按“垃圾密度”和“回收收益”动态选择待回收 Region,并在回收中完成复制与腾空。这意味着碎片控制是常态化、渐进式的——不是等崩了再压,而是边用边理。
关键信号:失败表现完全不同
- CMS 出现碎片问题,日志典型特征是:concurrent mode failure 后紧接 Abort Preclean 或 CMSCollector: abort,随后降级为 Serial Old
- G1 出现碎片压力,日志会显示 to-space exhausted(目标 Region 没整块空间可容纳复制对象),或 Mixed GC 中 Free CSet 远小于 Total CSet,说明它在“拼凑”Region 却收效甚微











