1、标记垃圾的算法
1.1引用技术算法
实现思路:给对象中添加一个引用计数器,每当有一个地方引用它,计数器就加 1;当引用失效,计数器就减 1;任何时候计数器 为 0 的对象就是不可能再被使用的,可以当做垃圾收集;
优点:执行效率高,程序执行受影响较小;
缺点:无法检测出循环引用的情况,导致内存泄露,如下:
public class ReferenceCountingGC {
public Object instance = null;
public static void testGC(){
ReferenceCountingGC objA = new ReferenceCountingGC ();
ReferenceCountingGC objB = new ReferenceCountingGC ();
// 对象之间相互循环引用,对象objA和objB之间的引用计数永远不可能为 0
objB.instance = objA;
objA.instance = objB;
objA = null;
objB = null;
System.gc();
}
}
1.2可达性分析算法(判断对象的引用链是否可达)
实现思路:通过一系列的称为 “GC Roots” 的对象作为起点,从这些节点开始向下搜索,节点所走过的路径称为引用链,当一个对象到 GC Roots 没有任何引用链相连的话,则证明此对象是不可用的,如下图objec 5、object 6、object 7。
2、四种引用状态
2.1、强引用
被强引用关联的对象不会被回收。使用 new 一个新对象的方式来创建强引用。
2.2、软引用
被软引用关联的对象只有在内存不够的情况下才会被回收。使用 SoftReference 类来创建软引用。
2.3、弱引用
被弱引用关联的对象一定会被回收,也就是说它只能存活到下一次垃圾回收发生之前。
使用 WeakReference 类来实现弱引用。
2.4、虚引用
又称为幽灵引用或者幻影引用。一个对象是否有虚引用的存在,完全不会对其生存时间构成影响,也无法通过虚引用取得一个对象。为一个对象设置虚引用关的唯一目的就是能在这个对象被回收时收到一个系统通知。
3、垃圾回收算法
4.1、标记-清除(Mark-Sweep)算法
将存活的对象进行标记,然后清理掉未被标记的对象。
缺点:
1、标记和清除过程效率都不高;
2、会产生大量不连续的内存碎片,导致无法给大对象分配内存
4.2、标记-整理(Mark-Compact)算法
让所有存活的对象都向一端移动,然后直接清理掉端边界以外的内存
4.3、复制(Copying)算法
将内存划分为大小相等的两块,每次只使用其中一块,当这一块内存用完了就将还存活的对象复制到另一块上面,然后再把使用过的内存空间进行一次清理。
缺点:只使用了内存的一半。