标记阶段通过可达性分析确定对象是否存活:从gc roots(如栈帧变量、静态变量、jni引用等)出发遍历引用链,被访问对象打上标记位,未被标记者判定为不可达;该过程不依赖引用计数或对象内部状态,仅反映当前gc周期中对象是否仍被程序逻辑需要。

标记-清除算法中,对象生命周期的“标记”并非由对象自身维护,而是由垃圾收集器在运行时统一管理——标记阶段本质是一次从根集(Roots)出发的可达性遍历,所有被遍历到的对象被视为“存活”,其生命周期在此刻被隐式延长;未被标记的对象则被判定为不可达,进入待回收队列。
标记阶段如何确定对象是否“存活”
标记不依赖对象内部字段或引用计数,而是基于图论中的可达性分析:
- GC从线程栈、寄存器、全局变量、JNI引用等根节点出发,递归访问所有直接或间接引用的对象;
- 每个被访问对象打上“已标记”位(通常复用对象头中1–2个bit,如Mark Word里的mark bit);
- 标记过程是原子的,多线程并发标记时需同步机制(如CAS或写屏障),避免重复标记或漏标。
标记与对象生命周期的实际关联
对象的“生命周期”在这里是运行时概念,不是编译期或语义上的作用域范围:
- 只要对象在某次GC标记阶段被根路径触及,就视为当前周期内“活跃”,哪怕它在Java代码中已无局部引用;
- 若对象仅被另一个待回收对象引用(即形成“孤岛循环”),因无法从根到达,整组对象都会被标记为不可达;
- 标记本身不改变对象状态,也不触发finalize()或清理逻辑——那是清除阶段或后续的引用队列处理环节。
常见实现细节与优化点
实际JVM(如HotSpot)中,标记位的使用和遍历策略会影响吞吐与暂停时间:
- 使用“三色标记法”(白-灰-黑)建模标记进度,支持并发标记,避免STW过长;
- 通过写屏障(Write Barrier)拦截引用更新,确保并发标记过程中不漏标新创建或新引用的对象;
- 标记位常与锁标志、哈希码等共用对象头空间,需谨慎设计布局,避免冲突(如CMS曾用高2位,ZGC改用着色指针替代显式标记位)。
标记本身不决定对象该活多久,只回答“此刻是否还被程序需要”——生命周期的边界,由每次GC的标记结果动态划定。











