标记清除算法分两步:先以gc roots为起点标记可达对象,再清除未标记对象内存;其优点是无需额外空间,缺点是产生内存碎片并引发stop-the-world。

标记清除算法是 Java 垃圾回收最基础的实现方式,核心就两步:先标出哪些对象还“活着”,再把没被标的全清掉。
标记阶段:从根出发,一路追踪可达对象
垃圾回收器会以 GC Roots(比如栈里的局部变量、静态字段、常量池引用、JNI 引用等)为起点,顺着所有引用链向下遍历。每遇到一个对象,就给它打上“存活”标记。这个过程不关心对象大小或位置,只判断“能不能从根到达”。不可达的对象,自然就不会被标记。
清除阶段:扫一遍堆,释放未标记内存
标记完后,回收器遍历整个堆内存区域,把所有没被打标记的对象所占空间直接归还给空闲列表。这部分内存之后可被新对象分配使用。
它的典型特点和实际影响
• 不需要额外内存空间,实现轻量,适合老年代这类大而稳的区域
• 但会产生大量不连续的内存碎片——比如清掉中间几个对象后,剩下东一块西一块的小空隙
• 碎片多了,后续分配大对象时可能找不到足够连续空间,哪怕总空闲量充足,也会被迫提前触发下一次 GC
• 每次执行都会引发 Stop-the-World,所有应用线程暂停,直到标记和清除完成
为什么现在很少单独用它
现代 JVM(如 G1、ZGC)已不再直接采用纯标记清除,而是融合优化思路。比如 CMS 收集器早期用标记清除来降低停顿,但因碎片问题最终被弃用;而 G1 的“标记-整理”混合策略,本质上是在标记后做局部整理,兼顾效率与空间利用率。理解它,关键是把握“标记靠可达性分析,清除不整理”这一逻辑主线。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











