JVM中主要有一下几种垃圾收集算法:
一.标记-清除算法
这是一种最基础的算法,算法分为标记、清楚两个阶段,首先标记出所有需要回收的对象,在标记完成后统一回收所有被标记的对象。
缺点:效率低,标记对象和清除对象两个阶段的效率都不高;空间利用率不高,标记清除之后可能会产生大量的不连续的内存碎片,当有一个很大的对象要分配空间时,就会找不到合适的内存给其分配,此时就会再一次触发垃圾回收动作。
二:复制算法
这总算法将内存划分为大小相等的两部分,每次只使用其中的一块,当使用的内存用完了,就将存活的对象复制到另一块内存中,然后对使用过的内存一次清理。这样每次只对使用的一块内存进行完整的回收,就不要考虑内存碎片的问题了,只需要移动堆顶指针,按顺序分配内存即可,实现起来简单,运行效率也得到了很大的提高。
缺点:空间代价比较大,只有一半的内存能用。但是可以根据需求,将存储存活对象的内存划分的小一些,这样可用的内存就会大很多。
三.标记-整理算法
这种算法是根据老年代的原理被提出来的,这种算法的标记过程与标记-清除算法的标记过程一样,只是标记完成之后不是直接清除,而是让所有存活的对象向一侧移动,然后只清理边界之外的内存即可。
四.分代收集算法
这是一种当前商业虚拟机都在使用的算法,其实这种算法的思想并不是新的,只是按照对象的生存周期不同将对象划分为几块。一般将Java堆划分为新生代和老年代,然后根据年代特点不同采用不同的算法。
新生代中对象存活率低,每一次垃圾回收都会回收掉大量的对象,此时采用“复制算法”,只需要付出很少的对象复制的成本就可以完成垃圾回收。
老年代中对象的生存周期较长,存活率高,没有额外的内存为其担保内存一定够用,所以使用“标记-清理”算法或者“标记-整理”算法进行垃圾回收。