常见的垃圾回收算法

41 阅读2分钟

1、引用计数法

原理: 为每个对象维护一个引用计数器,每当有一个地方引用它时,计数器值就加1;当引用被删除时,计数器值就减1。当计数器值为0时,该对象就不可达了,可以被回收。

优缺点: 实时性较高,无需等到内存不够时才开始回收;在垃圾回收过程中,应用无需挂起;但如果存在循环引用,即使对象实际上已经不再使用,计数器也可能永远不为0,导致内存泄漏。

2、标记清除法(Mark-Sweep)

原理: 分为两个阶段,首先是从根对象(roots)开始递归访问可达的对象,给其打上标记;然后遍历整个内存,回收未被打上标记的内存空间。

优缺点: 在存活对象比较多的情况下效率较高;但标记和清除过程效率较低,并且标记后可能会产生内存碎片。

3、标记压缩法(Mark-Compact)

原理: 在标记清除法的基础上,将所有存活的对象都向一端移动,然后直接清理掉边界以外的内存。

优缺点: 解决了标记清除法产生的内存碎片问题,但标记和压缩过程需要消耗更多时间。

4、复制算法(Copying)

原理: 将内存分为大小相等的两块,每次只使用其中一块。当这一块内存用完时,就将还存活的对象复制到另一块上,然后再把已使用过的内存空间一次清理掉。

优缺点: 在存活对象比较少的情况下效率高,没有碎片;但内存空间的使用率不高,只有原来的一半。

5、分代收集算法(Generational Collection)

原理: 根据对象存活周期的不同将内存划分为几块。一般是把Java堆分为新生代和老年代,新生代又可以分为Eden区、From Survivor区和To Survivor区。新生代中对象朝生夕灭,存活时间短,采用复制算法;老年代中对象存活率高,采用标记清除或标记压缩算法。

优缺点: 可以根据对象的不同存活周期选择合适的垃圾回收算法,提高垃圾回收效率;但需要维护多个内存区域,增加了管理的复杂性。