一、标记-清除算法
处理过程为:
1、标记可达对象(在对象头设置存活标记)
2、扫描全部内存空间,将不可达对象占用的内存放在一个空闲列表中。当需要分配新对象时,从空闲列表中取出空闲的内存地址。
优点:容易想到的算法实现
缺点:
(1)需要2次扫描,效率不高 【效率问题】
(2)标记清除后会产生大量不连续的碎片 【内存碎片】--基于这个缺点,进化产生了标记整理算法。
二、复制算法
为解决标记清除存在的2个问题,引入了复制算法:
1、它将内存分为大小相同的两块,每次使用其中的一块。当这一块的内存使用完后,就将还存活的对象复制到另一块去,然后再把使用的空间一次清理掉。
2、复制算法的处理逻辑是:进行可达性分析时,发现该对象存活,就直接复制到另一个区域
(1)优点:回收内存小效率高+无碎片。
(2)缺点显而易见: 1、浪费空间;2、存活时间久的对象复制次数过多。
复制算法的高效性是建立在存活对象少、垃圾对象多的前提下,适合于年轻代,不适合年老代,所以继续改进产生标记压缩算法
二、标记整理/标记压缩算法
处理过程为:
1、标记可达对象(在对象头设置存活标记)
2、扫描全部内存空间,将可达对象移动到空闲区域顺序存放。
优点:没有垃圾碎片
缺点:由于移动对象需要STW,所以效率比标记-清除算法效率低
四、分代回收算法
分代收集算法其实没什么新东西,只是把对象按存活率分块,然后选用合适的收集算法:
(1)存活率低的对象放在一起,称为年轻代,使用复制算法来收集。
(2)存活率高的对象放在一起,称为老年代,使用标记-清除或者标记-整理算法。
java1.8及之前,使用的就是分代收集模型;java9及之后,使用分区收集模型