标记整理算法(mark-compact)是java垃圾回收中用于解决内存碎片问题的核心机制,其具体做法分为“标记”和“整理”两个阶段:首先遍历所有存活对象并标记它们,然后让存活对象向内存起始端移动,从而消除碎片。该算法主要应用于老年代(old generation),特别是hotspot虚拟机中的部分收集器。

标记整理算法与标记清除算法的区别是什么
标记整理算法解决了标记清除算法产生的内存碎片问题。标记清除虽然实现简单,但回收后内存不连续;而标记整理在标记后会将存活对象紧凑排列,确保内存空间的连续性,便于为大对象分配空间。

public class MarkCompactDemo {
public static void main(String[] args) {
// 模拟老年代GC
System.out.println("Before GC: Memory is fragmented");
// 步骤1: Mark - 标记存活对象
// 假设对象A, B存活,C死亡
boolean objectA = true;
boolean objectB = true;
boolean objectC = false;
// 步骤2: Compact - 整理内存
// A, B 向前移动,填补C的空缺
System.out.println("After GC: Memory is compacted");
System.out.println("Fragmentation eliminated: " + !objectC);
}
}标记整理算法在哪些垃圾回收器中被使用
标记整理算法被Serial Old、Parallel Old以及CMS的Concurrent Mode Failure后备方案所使用。这些收集器在老年代回收时,通过移动对象位置来保证内存连续性,避免后续分配失败。
立即学习“Java免费学习笔记(深入)”;

public class GCDemo {
public static void main(String[] args) {
// 演示不同收集器的行为
String serialOld = "Serial Old";
String parallelOld = "Parallel Old";
String cmsFallback = "CMS Fallback";
// 这些收集器都依赖标记整理
System.out.println("Using Mark-Compact in: " + serialOld);
System.out.println("Using Mark-Compact in: " + parallelOld);
System.out.println("Using Mark-Compact in: " + cmsFallback);
}
}标记整理算法如何处理大对象的内存分配
标记整理算法通过移动存活对象,腾出连续的内存空间,从而能够成功分配大对象。如果没有整理阶段,即使总空闲内存足够,也可能因碎片化而无法容纳大对象。


















