标记-清除算法
标记-清除算法为最基础的垃圾收集算法。首先分为标记和清除两个阶段,首先标记出所有需要回收的对象,在标记完成后统一回收所有被标记的对象。
缺陷:1.效率问题:标记和清除两个过程效率都不高
2.空间问题:清除之后会存在大量的不连续的内存碎片,碎片太多,导致需要存储较大对象时找不到连续的内存而不得不提前触发垃圾收集。
复制算法:
为了解决标记清除的效率问题,出现了复制算法。它将可用的内存分为容量大小相等的两块,每次只使用其中的一块,当这一块用完时,就将还活着的对象复制到另一块上面,然后将已使用过的空间一次清理掉。
缺陷:将内存缩小为原来的一半,代价太高
现在的商业虚拟机新生代都是用复制算法来收集的,ibm公司的专门研究表明,新生代的对象98%是朝生夕死的,所以不需要安装1:1的比例来划分内存空间。而是将内存分为较大的eden空间和两块较小的survivor空间,他们的比例是8:1:1.当回收时,将eden中和survivor中还活着的对象一次性复制到另一个survivor空间上,然后清理掉eden区和刚才用过的survivor区。
我们没有办法保证每次回收都有不多于10%的对象存活,当survivor空间不够用时,需要依赖其他内存进行分配担保。这里指老年代。
标记-整理算法
复制收集算法在对象存活率较高时就要进行较多的复制操作,效率将会变低。如果不想浪费50%的空间,以应对被使用的内存中所有对象都100%存活的极端情况,所以在老年代一般不能选用这种算法。
根据老年代的特点,有人提出了另外一种标记-整理算法。是基于标记清除算法实现的,但是后续步骤不是直接对可回收对象进行清理,而是让所有存活的对象都向一端移动,然后直接清理掉其他的内存。
分代收集算法
当前商业虚拟机的垃圾收集都采用分代收集,根据对象存活周期的不同将内存划分为几块。Java将堆分为新生代,老年代,然后根据每一块的特性让他们采用最适合的算法。