介绍垃圾收集器的算法及引用详解
1、引用计数器
引用计数器在对象中添加一个引用计数器,当一个地方引用的时候,计数器+1,当引用失效时,计数器值就-1。
但是在Java里面存在对象循环引用:objA 和 objB都有字段instance,赋值令objA.instance = objB及objB.instance = objA,除此之外,这两个对象再无任何引用。因为互相引用着对方,导致它们的引用计数都不为零,引用计数算法也就无法回收它们。
2、可达性分析算法
从GC Roots开始搜索,路径称为“引用链”,如果某个对象到GC Roots间没有任何引用链相连,则证明此对象不可能再被使用的。
可达性分析算法是建立在引用的基础上,JDK1.2版本之后,Java对引用进行分类:强引用(Strongly Re-ference)、软引用(Soft Reference)、弱引用(Weak Reference)和虚引用(Phantom Reference)。
3、引用详解
(1)强引用:就是代码普遍的new,类似“Object obj = new Object()”。只要是强引用关系还存在,垃圾收集器就永远不会回收掉引用的对象。
(2)软引用:当内存溢出之前,GC会把这个对象进行回收,如果回收后依旧内存不足,则抛出溢出。
//创建一个强引用
Object o1 = new Object();
//创建一个软引用
SoftReference<Object> softReference = new SoftReference<>(o1);
应用场景:用于网页缓存、图片缓存等。
(3)弱引用:无论内存是否足够,只要发生垃圾收集,则该对象就被回收掉。
//创建一个强引用
ThreadLocal<?> threadLocal = new ThreadLocal<?>();
// 创建一个弱引用
WeakReference<ThreadLocal<?>> weakReference = new WeakReference<ThreadLocal>();
应用场景:ThreadLocal源码实现。深入理解ThreadLocal底层原理-CSDN博客
(4)虚引用:它不影响对象的生命周期,在任何时候都可能被垃圾回收器回收。主要用来跟踪对象被垃圾回收的活动。无法通过虚引用来取得一个对象实例。为一个对象设置虚引用关联的唯一目的只是为了能在这个对象被收集器回收时收到一个系统通知。
ReferenceQueue<String> queue = new ReferenceQueue<String>();
PhantomReference<String> = new PhantomReference<String>(new String("hello"),queue);
应用场景:堆外内存,当对象应用管理堆外内存的时候,如果虚引用对象被GC回收,则通知GC回收系统的内存,以防止系统内存溢出。