Skip to Content
面试题库Jvm[面试题] 什么是三色标记算法?为什么初始标记和重新标记需要 STW?

[面试题] 什么是三色标记算法?为什么初始标记和重新标记需要 STW?

📖 版块 A:知识讲解版 (温故知新)

  • 三色标记算法

    1. 白色:尚未被访问到的对象,默认是垃圾候选。
    2. 灰色:已经被发现,但其引用出去的对象还没有全部扫描完。
    3. 黑色:对象本身以及它引用出去的对象都已经扫描完。
  • 并发标记的问题

    1. 如果用户线程和 GC 线程同时修改对象引用关系,就可能破坏标记过程。
    2. 这会导致漏标或误标。
  • 为什么初始标记需要 STW

    1. 需要快速从 GC Roots 建立初始可达对象集合。
    2. 这个起点必须尽量一致可靠。
  • 为什么重新标记需要 STW

    1. 并发标记期间,用户线程仍然在修改引用关系。
    2. 重新标记要把这期间遗漏的变化补回来,修正最终结果。
  • 一句话理解

    1. 并发标记可以并发做大部分脏活,但在“确定起点”和“最终收口”这两个阶段,仍然需要 STW 保证一致性。

🎤 版块 B:面试实战版 (高手逐字稿)

Q:什么是三色标记算法?为什么初始标记和重新标记需要 STW?

💬 高手逐字稿

三色标记算法,本质上是垃圾回收器在并发标记时,用来管理对象扫描状态的一种抽象模型。

它会把对象分成三类:

  • 白色,表示还没访问到,默认可能是垃圾;
  • 灰色,表示这个对象已经发现了,但它引用出去的对象还没扫完;
  • 黑色,表示这个对象和它能到达的引用都已经处理完了。

如果整个程序是静止的,这套模型很好用。但问题在于,现代回收器很多时候是并发标记,也就是 GC 标记时,用户线程还在继续运行,还在不断修改对象之间的引用关系。

这就会带来一个核心风险:GC 看到的对象图在变化。 一旦变化时机不巧,就可能出现本来还活着的对象没有被正确标记,也就是漏标。

所以为什么初始标记和重新标记必须 STW?

因为 初始标记 要快速确定从 GC Roots 出发的起点集合,这一步如果不停顿,根集合本身就在漂移,后面整条标记链都会不可靠。

重新标记 则是为了在并发标记结束之后,修正用户线程在并发阶段造成的引用变化。你可以把它理解成最后一次“对账”,确保没有漏掉重要改动。

所以并发回收的正确理解应该是:它不是完全不要 STW,而是把大部分耗时工作并发掉,只在最关键的起点和收尾阶段保留短暂 STW。

最后更新于:
⏱️

登录后开始阅读

当前 MVP 版本只开放邮箱密码登录注册。完成登录后即可进入面试题内容。

还没有账号?先去注册