标记-清理过程从GCRoots出发,通过三色标记法识别存活对象,白色对象被回收。清理阶段释放内存但产生碎片,部分算法增加整理步骤消除碎片。并发标记需强三色不变性避免漏标,CMS因浮动垃圾和碎片被废弃。
GC的标记-清理过程,核心是判断哪些对象还活着,再回收它们的空间。不同垃圾回收器在细节上各有差异,但主流的标记-清理(Mark-Sweep)及其优化变体(如标记-整理 Mark-Compact)都遵循这一逻辑主线。下面以最典型的三色标记法为基础,结合实际执行阶段,详细拆解这条链路。
标记阶段不会直接修改对象内容,而是为每个对象维护一个“颜色”状态,进行追踪:
长期稳定更新的攒劲资源: >>>点此立即查看<<<
整个过程从GC Roots(如栈帧局部变量、静态字段、JNI引用等)出发,将所有直接可达的对象涂成灰色,放入标记队列;然后循环取出灰色对象,将其引用的白色对象涂灰并入队,自身涂黑;直到队列为空。最终,所有黑色对象即为存活对象,剩下的白色对象就是可回收的垃圾。
清理阶段会扫描整个堆(或当前收集区域,如老年代),识别出仍为白色的对象:
例如,Serial GC或CMS在初始标记加重新标记后的清理,就采用这种方式。CMS后期因并发清理无法处理浮动垃圾,还需要额外触发一次STW清理。
标记-清理本身不整理内存,而标记-整理(如Serial Old、Parallel Old、ZGC的部分阶段)则会在清理前增加整理步骤:
需要注意的是,G1和ZGC并不采用传统整理,而是通过Region划分加复制(G1的Evacuation)或读屏障加重映射(ZGC的染色指针)来实现低延迟与空间整合。
面试中容易被追问的点通常包括:
理解标记-清理不能孤立地看,它和内存布局、写屏障、并发控制深度耦合。掌握三色抽象、GC Roots范围,以及各算法在吞吐量、延迟与内存利用率之间的权衡,才能真正吃透这条链路。
侠游戏发布此文仅为了传递信息,不代表侠游戏网站认同其观点或证实其描述