强引用,软引用,弱引用,幻象引用有什么区别?

简介: 强引用,软引用,弱引用,幻象引用有什么区别?

强引用,软引用,弱引用,幻象引用有什么区别?


不同的引用类型,主要体现的是对象的不同的可达性(reachable)状态和对垃圾收集的影响。


  • 所谓强引用 (Strong  Reference) 就是我们常见的普通对象引用,只要还有强引用指向一个对象,就能表明对象还活着,垃圾回收不回收这种对象
  • 软引用,是一种相对强引用弱化一些的引用,只有当 JVM 认为内存不足时,才会试图回收软引用指向的对象。JVM 会确保在排除 OutOfMemoryError 之前,清理软引用指向的对象,软引用通常用来实现内存敏感的缓存,如果还有空闲内存,就可以暂时保留缓存,当内存不足时,清理掉,这样就保证了使用缓存的同时,不会耗尽内存。
  • 弱引用,比软引用拥有更短的生命周期,在垃圾回收线程扫码所管辖的内存区域的过程中,一大发现了只具有弱引用的对象,不管当前内存空间是否足够,都会回收它的内存,由于垃圾回收器是一个优先级,因此不一定很快发现那些只有弱引用的对象。
  • 虚引用,形同虚设 ,虚引用不会决定对象的生命周期,如果一个对象仅持有虚引用,其实就和没有任何引用一样。在任何时候都可能被垃圾回收器回收。虚引用和软引用的一个区别是,虚引用必须和引用队列(ReferenceQueue)联合使用。当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之关联的引用队列中。


640.png


四种引用类型对比


引用类型 被垃圾回收时间 用途 生存时间
强引用 从来不会 对象的一般状态 JVM 停止运行时终止
软引用 当内存不足时 对象缓存 内存不足时终止
弱引用 正常垃圾回收时 对象缓存 垃圾回收后终止
虚引用 正常垃圾回收时 跟踪对象的垃圾回收 垃圾回收后终止

四种引用的应用场景


强引用


强引用是使用最普遍的引用,一般声明如下:


Object strongReference = new Object();

如果要对强引用进行垃圾回收,需要设置强引用对象为 null ,或者让其超出对象的生命周期范围,则认为改对象不存在引用。


strongReference = null;

可以看下 ArrayList 是如何进行内存释放的


public void clear() {
        modCount++;
        // clear to let GC do its work
        for (int i = 0; i < size; i++)
            elementData[i] = null;
        size = 0;
    }

软引用


软引用可用来实现内存敏感的高速缓存。

使用如下:


// 强引用
String strongReference = new String("abc");
// 软引用
String str = new String("abc");
SoftReference<String> softReference = new SoftReference<String>(str);

软引用可以和一个引用队列(ReferenceQueue)联合使用,如果软引用所引用的对象被垃圾回收,Java虚拟机就会把这个软引用加入到与之关联的引用队列中。


ReferenceQueue refQueue = new ReferenceQueue();
SoftReference softRef = new SoftReference(obj, refQueue);

软引用垃圾回收


if(JVM内存不足) {
      // 将软引用中的对象引用置为null
      str = null;
      // 通知垃圾回收器进行回收
      System.gc();
  }

代表软引用的类:java.lang.ref.SoftReference 代表弱引用的类:java.lang.ref.WeakReference 代表虚引用的类:java.lang.ref.PhantomReference 他们同时继承了:java.lang.ref.Reference


public static void soft() throws Exception {
        Object obj = new Object();
        SoftReference<Object> softRef = new SoftReference<Object>(obj);
        System.out.println(softRef.get()); //有时候会返回Null
        // java.lang.Object@f9f9d8 System.out.println(refQueue.poll());
        // null
        // 清除强引用,触发GC
        obj = null;
        //System.gc();
        System.out.println(softRef.get());
        //Thread.sleep(200);
        //System.out.println(refQueue.poll());
    }

弱引用


弱引用和软引用的区别在于:弱引用拥有更短暂的生命周期,不管内存够不够,都会回收,都会回收它的内存。


Object obj = new Object();
WeakReference<Object> weakReference = new WeakReference<Object>(obj);
obj = null;
System.gc();
System.out.println(weakReference.get());// 有时候会返回Null
System.out.println(weakReference.isEnqueued());//判断是否有垃圾回收标记,表示即将回收的垃圾

虚引用


// 虚引用
Object obj = new Object();
ReferenceQueue refQueue = new ReferenceQueue();
PhantomReference<Object> phantomReference = new PhantomReference<Object>(obj, refQueue);
System.out.println(phantomReference.get());  // 永远返回Null
System.out.println(phantomReference.isEnqueued()); //返回时否从队列中删除

640.png


  • 强可达(Strongly Reachable),就是当一个对象可以有一个或多个线程可以不通过各种引用访问到的情况。比如,我们新创建一个对象,那么创建它的线程对它就是强可达。
  • 软可达(Softly Reachable),就是当我们只能通过软引用才能访问到对象的状态。
  • 弱可达(Weakly Reachable),类似前面提到的,就是无法通过强引用或者软引用访问,只能通过弱引用访问时的状态。这是十分临近fnalize状态的时机,当弱引用被清除的时候,就符合finalize的条件了。
  • 幻象可达(Phantom Reachable),上面流程图已经很直观了,就是没有强、软、弱引用关联,并且finalize过了,只有幻象引用指向这个对象的时候。当然,还有一个最后的状态,就是不可达(unreachable),意味着对象可以被清除了。

Java中4种引用的级别和强度由高到低依次为:强引用 -> 软引用 -> 弱引用 -> 虚引用

相关文章
|
缓存 Java 程序员
Java 中的强引用、弱引用、软引用和虚引用
引用方式内存不足时垃圾回收机制启动时其余情况强引用否否否软引用是否否弱引用是是否虚引用可能可能可能在一般的程序中,弱引用和虚引用很少会被用到,强引用天天都在用就不必我说了,在有些情况下(如资源文件很大,但并不是全部要在同一时刻使用)我们会使用软引用来代替原来的强引用,一是可以避免某些情况下产生的 OOM,此外,它可以减少程序使用的内存,加速程序的运行。
101 1
|
6月前
|
缓存 Java
【JAVA】强引用、软引用、弱引用、幻象引用有什么区别?
幻象引用:幻象引用是最弱的引用类型,几乎不影响对象的生命周期。它们主要用于在对象被回收前进行某些预处理操作,例如在对象被销毁时执行特定的清理任务。
58 0
|
6月前
|
Java
【JVM】深入理解Java引用类型:强引用、软引用、弱引用和虚引用
【JVM】深入理解Java引用类型:强引用、软引用、弱引用和虚引用
507 0
|
6月前
|
缓存 Java 程序员
Java垃圾回收: 什么是强引用、软引用、弱引用和虚引用?
Java垃圾回收: 什么是强引用、软引用、弱引用和虚引用?
74 2
|
Java
JVM学习日志(八) 强引用,软引用,弱引用,虚引用
强引用,软引用,弱引用,虚引用 简述
101 0
JVM学习日志(八) 强引用,软引用,弱引用,虚引用
|
算法 Java C++
14-理解Java中的不同引用类型:强引用、软引用、弱引用和虚引用
这篇文章将深入探讨Java中的四种引用类型:强引用、软引用、弱引用和虚引用。我们将逐一解释每种引用类型的特性和用途。
114 0
14-理解Java中的不同引用类型:强引用、软引用、弱引用和虚引用
|
Java
强引用、软引用、弱引用、虚引用的区别?
强引用、软引用、弱引用、虚引用的区别?
83 0
|
Java C++
Java引用类型:强引用,软引用,弱引用,虚引用
Java引用类型:强引用,软引用,弱引用,虚引用
83 0
|
缓存 Java 关系型数据库
强引用、软引用、弱引用、幻象引用有什么区别和使用场景
强引用、软引用、弱引用、幻象引用有什么区别和使用场景
217 1
|
算法 Java
java中的强引用、软引用、弱引用、虚引用
java中将引用类型分为强引用、软引用、弱引用、虚引用。之所以要这么划分,还是为了GC时更好的对对象进行处理。因为jvm已经明确了各种引用的GC方式,所以谈四种引用最好是和GC一起聊才会有意义(个人愚见)。
147 0