标记-清除算法(Mark-Sweep)
标记:从根对象开始遍历,标记所有被引用的对象
清除:堆内存,从头到尾遍历,发现没有被标记的,回收。
优点:实现简单
缺点:效率不高(两次遍历)。
GC时需要STW。
这种方式会导致清理出的内存不连续。所以需要维护空闲列表。
什么是清除、回收?
对象并没有被正在的清除,而是把对象地址放在空闲列表里,需要用内存时,覆盖他。
复制算法
原理:将活着的内存空间分为两块,每次只使用一块,回收时,将存活的对象复制到另一块内存中,原来这块完全清除。
优点:没有标记清除两次遍历,实现简单,运行高效。
内存连续。
缺点:需要两倍的内存空间
复制操作,导致内存和时间开销大(需要频繁调整指针)
如果非垃圾的对象很多,影响效率。
标记-压缩算法(Mark-Compact)
原理:标记:从根对象开始遍历,标记所有被引用的对象
压缩(整理):把被标记的对象,移动到内存的一端,按顺序放(碎片整理),然后清除未标记对象。
优点:消除了内存碎片化的问题,只需保留内存起始指针的位置(指针碰撞)
缺点:效率低于 复制算法和标记-清除算法
移动对象,需要调整引用。
移动时要STW
标记-清除 | 标记-压缩 | 复制算法 | |
---|---|---|---|
速度 | 中 | 慢 | 快 |
空间开销 | 少(有碎片) | 少(无碎片) | 2倍内存(无碎片) |
移动对象 | 无 | 有 | 有 |
分代收集算法
不同代中对象生命周期不同,因此对不同代采用不同的算法,以提高效率
年轻代:区域较小,对象生命周期短,存活率低,回收频繁,使用复制算法。survivor区的设计和复制算法吻合。
**老年代:**区域大,生命周期长,存活率高,回收不频繁,不适合复制算法(非垃圾对象多,复制开销大)混合使用标记清除和标记压缩
Hotspot CMS垃圾回收器:基于标记清除算法。面对碎片问题时,CMS调用Serial Old垃圾回收器,基于标记压缩算法。
增量收集算法
如果一次性将所有垃圾回收,那么会长时间STW
改进方法:垃圾收集线程只回收一小片区域内存空间,和应用进程频繁切换,知道垃圾回收完成。(并发)
缺点:造成系统吞吐量下降。
分区算法
一大块内存区域分成多个小块,每次回收若干个小区间,从而减少STW时间。
和上面的区别很模糊,一个分区一个不分区。