当前商业虚拟机的垃圾收集器,大多数都遵循了“分代收集”(Generational Collection)[1]的理论进 行设计,分代收集名为理论,实质是一套符合大多数程序运行实际情况的经验法则,它建立在两个分代假说之上:
弱分代假说(Weak Generational Hypothesis):绝大多数对象都是朝生夕灭的。
强分代假说(Strong Generational Hypothesis):熬过越多次垃圾收集过程的对象就越难以消 亡。
把分代收集理论具体放到现在的商用Java虚拟机里,设计者一般至少会把Java堆划分为新生代 (Young Generation)和老年代(Old Generation)两个区域[2]。顾名思义,在新生代中,每次垃圾收集 时都发现有大批对象死去,而每次回收后存活的少量对象,将会逐步晋升到老年代中存放。
对于分代理论,由于会存在老年代引用新生代的情况,这对于回收对象时的判断会造成性能影响,所以还应该有下面假说
上面条结论可根据前两条假说逻辑推理得出的隐含推论:存在互相引用关系的两个对象,是应该倾向于同时生存或者同时消亡的。
下面是一些常见的分代收集名词
部分收集(Partial GC):指目标不是完整收集整个Java堆的垃圾收集,其中又分为:
新生代收集(Minor GC/Young GC):指目标只是新生代的垃圾收集。
老年代收集(Major GC/Old GC):指目标只是老年代的垃圾收集。目前只有CMS收集器会有单独收集老年代的行为。
混合收集(Mixed GC):指目标是收集整个新生代以及部分老年代的垃圾收集。目前只有G1收集器会有这种行为。
整堆收集(Full GC):收集整个Java堆和方法区的垃圾收集。
标记-清除算法(Mark and Sweep Algorithm)是一种经典的垃圾回收算法,用于识别和释放不再被引用的对象,从而回收内存空间。它包括两个主要阶段:标记(Mark)和清除(Sweep)。
下面是标记-清除算法的工作原理:
上面有一点需要注意的是,标记对象可以是所有需要回收的对象,在标记完成后,统一回收掉所有被标记的对象,也可以反过来,标记存活的对象,统一回收所有未被标记的对象。
下面是标记-清除算法的示意图

标记-清除算法的优点是它可以回收不再被引用的对象,但它也有一些缺点:
标记-复制算法(Mark and Copy Algorithm)是一种用于垃圾回收的算法,它解决了标记-清除算法中出现的内存碎片问题。标记-复制算法主要用于新生代(Young Generation)的垃圾回收,通常分为两个阶段:标记(Mark)和复制(Copy)。
下面是标记-复制算法的工作原理:
标记(Mark)阶段:
复制(Copy)阶段:
清理(Clean-Up)阶段:
示意图如下

标记-复制算法的主要优点是它有效地解决了内存碎片问题。因为被复制的对象都被整齐地排列在一起,"From"区变为空,所以不会出现内存碎片化的情况。这提高了内存的利用率,减少了分配大对象时可能出现的空间不足问题。缺点就是比较浪费空间。
标记-复制算法主要用于新生代的垃圾回收,而老年代通常使用其他算法,如标记-清除或标记-整理算法。这些不同的垃圾回收算法结合在一起,构成了现代Java虚拟机中的复杂垃圾回收策略,以提高内存管理的效率和性能。
标记-整理算法(Mark and Compact Algorithm)是一种用于垃圾回收的算法,通常用于老年代(Old Generation)的内存回收。它是标记-清除算法的改进版本,主要解决了标记-清除算法可能导致的内存碎片问题。
相较于标记-清楚算法只是多了一个整理的过程
整理(Compact)阶段:
示意图如下
