标记-清除算法虽不再单独使用,但其核心思想仍是现代垃圾回收的基石,广泛应用于老年代GC、嵌入式环境及数据库内存管理,并通过分代收集、并发标记、增量清除等工程优化持续演进。

标记-清除算法本身已很少在现代系统中单独使用,但它仍是理解垃圾回收机制的基石,其思想深度融入主流运行时环境的设计逻辑中。
仍在底层支撑关键场景
尽管JVM、V8、.NET CLR等主流运行时早已不再纯用标记-清除,但它的核心逻辑仍保留在多个环节:
- 老年代(Old Generation)GC的初始阶段:如G1、ZGC、Shenandoah在部分回收区域仍采用“标记+局部清理”策略,本质是标记-清除的变体;
- 某些嵌入式或资源受限环境(如MicroPython、TinyGo的部分配置)仍启用简化版标记-清除,因其代码体积小、无移动开销;
- 数据库内存池管理(如PostgreSQL的内存上下文)、游戏引擎资源跟踪(Unity的Managed Heap早期版本)中,也可见其轻量级实现。
工业级改进已成标配
为克服原始算法的碎片化与停顿问题,实际系统普遍采用组合式优化:
- 分代收集:将堆划分为年轻代与老年代,年轻代用复制算法(低延迟),老年代在标记后引入整理或增量清理,避免全堆扫描;
- 并发标记:如CMS(已弃用但影响深远)、G1、ZGC均把标记过程与用户线程并发执行,大幅缩短STW(Stop-The-World)时间;
- 增量清除 + 懒清除:不一次性遍历整个堆,而是按页或按卡(card)分批处理,配合写屏障追踪新引用,平衡吞吐与响应性;
- 混合回收策略:例如G1既做标记,又按收益排序回收Region;ZGC通过染色指针+读屏障实现几乎零停顿,但标记阶段仍依赖可达性分析这一核心思想。
它不是被淘汰,而是被重构
标记-清除没有消失,只是从“独立算法”演变为“基础能力模块”:
- 所有追踪式GC都必须回答“哪些对象可达”——这正是标记阶段的本质任务;
- 现代GC调试工具(如JFR、Chrome DevTools Memory Profiler)的“对象图分析”功能,底层依赖的就是标记遍历逻辑;
- 安全关键系统(如航空软件中的实时Java平台)仍会指定基于标记-清除的确定性回收子集,确保可验证性。
真正退出舞台的是“朴素两阶段全堆扫描”的实现方式,而不是标记与清除这两个基本动作。工业实践证明:保留标记的语义正确性,再用工程手段优化清除的时机、粒度与并发性,才是可持续路径。

















