垃圾收集算法
1 标记-清除算法
标记清除算法是最常见的垃圾收集算法。当堆空间被耗尽的时候,就会停止整个程序(STW),进行两项操作。
第一是标记,第二是清除
标记: 从根节点开始遍历,标记所有被引用的对象
清除: 从堆内存中从头到尾进行遍历,如果发现没有被标记的对象就进行回收。
缺点: 1.效率不高 2. 这种方式清理出来的空间不连续,会产生内存碎片
2 复制算法
复制算法的高效性,是建立在存货对象少,垃圾对象多的的前提下。显然比较适合新生代,不适合老年代。
过程: 将存活的内存空间分为两块,每次只使用一块,在垃圾回收的时候将正在使用的内存块中存活的对象复制到另一块中,之后清理正在使用的内存块。
缺点: 此算法缺点也比较明显,就是需要两倍的内存空间
3 标记-压缩(整理)算法
标记整理算法等同于 标记清除算法后,但后续步骤不是直接对可回收对象回收,⽽是让所有存活的对象向⼀端移动,然后直接清理掉端边界以外的内存。
过程:
1. 第一阶段和标记清除算法一样,从根节点开始标记处所有的存活对象
2. 第二阶段将所有的存储对象压缩到内存的一端,按顺序排放
3. 之后清理边界外的内存空间
4 分代收集算法
当前虚拟机的垃圾收集都采⽤分代收集算法,这种算法没有什么新的思想,只是根据对象存活周期的不同将内存分为⼏块。⼀般将 java 堆分为新⽣代和⽼年代,这样我们就可以根据各个年代的特点选择合适的垃圾收集算法。
⽐如在新⽣代中,每次收集都会有⼤量对象死去,所以可以选择复制算法,只需要付出少量对象的复制成本就可以完成每次垃圾收集。⽽⽼年代的对象存活⼏率是⽐较⾼的,⽽且没有额外的空间对它进⾏分配担保,所以我们必须选择**“标记-清除”或“标记-整理”**算法进⾏垃圾收集。