标记-清除、复制、标记-整理是gc三大核心算法:标记阶段均基于根可达性分析识别存活对象;清除直接释放未标记内存但产生碎片;复制通过空间换时间避免碎片,适用于新生代;整理则移动存活对象消除碎片,适合老年代。

GC算法的核心在于如何高效识别并回收不再使用的对象。标记、清除、整理和复制这四种机制,本质是围绕“哪些能回收”和“怎么腾空间”两个问题展开的不同策略。
标记:确定哪些对象还“活着”
标记阶段是所有GC算法的起点,目标是遍历对象图,从GC Roots出发,递归标记所有可达对象。未被标记的对象即为垃圾。关键点在于GC Roots的构成——包括栈帧中的局部变量、静态变量、JNI引用等。一旦漏标(如并发场景中对象被新引用),会导致错误回收;误标(本该回收却标记了)则造成内存浪费。现代JVM通常采用三色标记法(白-未访问、灰-已访问但子节点未处理、黑-已访问且子节点全处理)来支持并发标记,避免漏标。
清除:直接回收标记出的垃圾
清除阶段遍历堆内存,将所有未被标记的对象所占空间释放。优点是实现简单、停顿短;缺点是产生大量不连续的内存碎片,导致后续大对象分配失败(即使总空闲空间足够)。CMS收集器就采用“标记-清除”,因此需要配合预留空间或触发Concurrent Mode Failure后的Full GC来应对碎片问题。
整理:把存活对象搬到一起,消除碎片
整理阶段在清除前,先将所有存活对象向内存一端移动,然后直接清理边界外的空间。这样既回收了垃圾,又保证了剩余空间连续。Serial Old和Parallel Old默认使用“标记-整理”,适合老年代这种对象生命周期长、碎片敏感的区域。代价是移动对象需更新所有指向它的引用,带来额外开销,且必须STW(Stop-The-World)执行。
复制:用空间换时间,专治新生代高频回收
复制算法将堆划为两块相等区域(如Eden + From/To Survivor),每次只使用其中一块。GC时,将当前使用区中存活对象复制到另一块空闲区,再清空原区域。天然解决碎片问题,且只需顺序写入,效率高。但代价是牺牲50%可用空间(实际通过动态调整Survivor比例缓解)。Minor GC普遍采用此策略,如ParNew、G1的Young GC阶段。











