商城首页欢迎来到中国正版软件门户

您的位置: 首页 > 文章列表 > 编程开发 > CMS与G1在碎片化处理上的根本技术差异

CMS与G1在碎片化处理上的根本技术差异

  发布于2026-07-08 阅读(0)

扫一扫,手机访问

说到CMS和G1在碎片处理上的区别,很多人的第一反应是“CMS碎片多,G1碎片少”。这话对,但没说到根上。两者真正的分野,不在于“会不会产生碎片”,而在于一个更关键的问题:碎片是不是会立刻堵住内存分配的通道。CMS因为算法和内存布局的设计,碎片一旦出现,分配就可能直接失败;G1靠分区和整理机制,把碎片困在局部区域,不让它挡全局的路。

CMS与G1在碎片化处理上的根本技术差异

算法底层:标记-清除 vs 标记-整理

CMS底层用的是标记-清除算法——只回收垃圾,不挪动活对象。老年代是一整块连续的地址空间,回收之后空闲内存变成零零散散的小块。这时候如果你要分配一个比较大的对象,比如数组或者缓存块,就必须找到一块连续的空闲区域。一旦找不到,哪怕总空闲空间还有不少,也会直接触发 promotion failureconcurrent mode failure,然后退化成Serial Old全堆压缩GC——代价极高,停顿很长。

G1走的是另一条路:标记-整理(其实是局部复制)。在筛选回收阶段,它把选中的Region里的存活对象复制到别的Region,原Region直接整体释放。这个动作本身就是空间整理——用完的Region干干净净,不会有“明明有空位却塞不进”的假性耗尽问题。

内存组织:连续段 vs 固定大小Region

CMS的老年代是单一连续的物理段,碎片随着运行时间越积越多,而且没法隔离——碎成渣了也得硬扛。而G1把堆切成固定大小的Region(默认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 PrecleanCMSCollector: abort,然后降级为Serial Old——说明系统已经撑不住了。
  • G1出现碎片压力时,日志会显示to-space exhausted,意思是目标Region里没有整块空间可以容纳复制对象;或者Mixed GC中Free CSet远小于Total CSet——说明它正在东拼西凑Region,但收效甚微,性能开始下滑。

看懂这些信号,才能在实际调优时对症下药。而不是看到“碎片”两个字就盲目切换GC。

本文转载于:https://www.php.cn/faq/2787955.html 如有侵犯,请联系zhengruancom@outlook.com删除。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。

热门关注