Java中的四种引用和引用队列的概念

四种引用类型

  1. 强引用(StrongReference)
    强引用就是指在程序代码之中普遍存在的,比如下面这段代码中的object和str都是强引用:
Object object = new Object();
String str = "hello";

只要某个对象有强引用与之关联,JVM必定不会回收这个对象,即使在内存不足的情况下,JVM宁愿抛出OutOfMemory错误也不会回收这种对象。如果想中断强引用和某个对象之间的关联,可以显式地将引用赋值为null,这样一来的话,JVM在合适的时间就会回收该对象。

  1. 软引用(SoftReference)
    软引用是用来描述一些有用但并不是必需的对象,在Java中用java.lang.ref.SoftReference类来表示。对于软引用关联着的对象,只有在内存不足的时候JVM才会回收该对象。因此,这一点可以很好地用来解决OOM的问题,并且这个特性很适合用来实现缓存:比如网页缓存、图片缓存等。

注意:只有在内存不足的时候JVM才会回收软引用关联着的对象。

  1. 弱引用(WeakReference)
    弱引用也是用来描述非必需对象的,当JVM进行垃圾回收时,无论内存是否充足,都会回收被弱引用关联的对象。
public static void main(String[] args) {
        
        WeakReference str = new WeakReference(new String("hello"));
        System.out.println(str.get());
        System.gc();
        System.out.println(str.get());
}

运行上面的代码输出

hello
null

4.虚引用(PhantomReference)
虚引用和前面的软引用、弱引用不同,它并不影响对象的生命周期。在java中用java.lang.ref.PhantomReference类表示。如果一个对象与虚引用关联,则跟没有引用与之关联一样,在任何时候都可能被垃圾回收器回收。设置虚引用的目的是为了被虚引用关联的对象在被垃圾回收器回收时,能够收到一个系统通知。虚引用必须和引用队列关联使用,当垃圾回收器准备回收一个对象时,如果发现该对象具有虚引用,那么在回收之前会首先把该对象的虚引用加入到与之关联的引用队列中。程序可以通过判断引用队列中是否已经加入虚引用,来了解被引用的对象是否被GC回收。

四种引用类型使用场景

  • 强引用类型是在代码中普遍存在,无须解释
  • 软引用和弱引用:两者都可以实现缓存功能,但软引用实现的缓存通常用在服务端,而在移动设备中的内存更为紧缺,对垃圾回收更为敏感,因此android中的缓存通常是用弱引用来实现(比如LruCache)
  • 虚引用 为了被虚引用关联的对象在被垃圾回收器回收时,能够收到一个系统通知

引用队列 ReferenceQueue

使用SoftReference,WeakReference,PhantomReference 的时候,可以关联一个ReferenceQueue。那么当垃圾回收器准备回收一个被引用包装的对象时,该引用会被加入到关联的ReferenceQueue。程序可以通过判断引用队列中是否已经加入引用,来了解被引用的对象是否被GC回收。

参考链接:

  1. 深入JVM对象引用
  2. Java 如何有效地避免OOM:善于利用软引用和弱引用
  3. Android中四种引用以及适用场景
  4. ReferenceQueue的使用

你可能感兴趣的:(Java中的四种引用和引用队列的概念)