分代收集算法
大多数程序的运行情况符合以下两个假设:
- 弱分代假设:绝大多数的对象都是朝生夕灭的;
- 强分代假设:熬过多次 GC 的对象就越难以消亡。
这两个分代假设奠定了多款常用的垃圾收集器的一致设计原则:收集器应该将 Java 堆划分为不同的区域,然后依据对象的年龄分配到不同的区域。
在 Java 堆被划分出不同的区域之后,垃圾收集器才可以每次只回收其中一个或者某些部分的区域。因此才有「Minor GC」、「Major GC」、「Full GC」 这样的回收类型的划分。
标记-清除算法
标记-清除算法是最基础的收集算法,分别为「标记」和「清除」两个阶段,首先标记出所有需要回收的对象,在标记完成之后,统一回收掉所有被标记的对象。
标记-清除算法的缺点如下:
- 第一是执行效率不稳定,如果 Java 堆中包含大量对象,并且大部分是需要被回收的,这时就需要进行大量标记和清除的动作,导致标记和清除两个过程的执行效率随着对象的数量增加而降低。
- 在标记和清除之后可能会产生大量不连续的内存碎片,空间碎片太多。
标记-复制算法
标记-复制算法是为了解决标记-清除算法在回收大量对象时的执行效率低的问题。标记-复制算法将内存划分为大小相等的两个区域,每次只会用其中一块,当这一块的内存用完了,就将还存活着的对象复制到另一块上面去,然后再把已经使用过的内存一次性清空。
标记-整理算法
标记-整理算法是为了解决标记-清除算法的内存空间碎片化问题。标记-整理算法会将可回收的对象向内存空间的一端移动,然后再清理边界以外的内存空间。