WeakReference弱引用

538 阅读2分钟

WeakReference弱引用

什么是弱引用

顾名思义,弱引用,当一个对象仅仅被weak reference(弱引用)指向并且没有其它对象strong reference(强引用)指向,这时GC运行那么这个对象将被回收。

WeakReference类

weakreference类只有两个构造方法

 public WeakReference(T referent) {
     super(referent);
 }
 ​
 /**
 和上诉构造方法的区别是多了一个引用队列,当GC回收对象时,将引用对象回收而将被引用对象放入ReferenceQueue
 */
 public WeakReference(T referent, ReferenceQueue<? super T> q) {
     super(referent, q);
 }

使用WeakReference

前置准备

 package com.example.demo.weakreference;
 ​
 public class Apple {
     private String name;
 ​
     public Apple(String name){
         this.name = name;
     }
 ​
     public String getName() {
         return name;
     }
 ​
     public void setName(String name) {
         this.name = name;
     }
 ​
     /**
      * 对象回收最后调用方法,回收时执行
      * @throws Throwable
      */
     @Override
     protected void finalize() throws Throwable {
         super.finalize();
         System.out.println("Apple "+ name + " finalize");
     }
 ​
     @Override
     public String toString() {
         return "Apple{" +
                 "name='" + name + ''' +
                 '}'+", hashcode:"+this.hashCode();
     }
 }
 package com.example.demo.weakreference;
 ​
 import java.lang.ref.WeakReference;
 ​
 /**
  * 弱引用有两种构造方法,多的一种只是多了一个队列
  *    public WeakReference(T referent) {
  *         super(referent);
  *     }
  *
  *     public WeakReference(T referent, ReferenceQueue<? super T> q) {
  *         super(referent, q);
  *     }
  * 例如:
  * WeakReference<Apple> appleWeakReference = new WeakReference<>(apple);
  * Apple apple2 = appleWeakReference.get();
  * apple是弱引用对象而appleWeakReference是被弱引用对象
  */
 public class Salad extends WeakReference<Apple> {
 ​
     public Salad(Apple referent) {
         super(referent);
     }
 }

构造方法一

 package com.example.demo.weakreference;
 ​
 public class Client1 {
     public static void main(String[] args) {
         Salad salad = new Salad(new Apple("红富士"));
 ​
         // 通过weakreference调用Apple
         System.out.println("Apple1 "+salad.get());
 ​
         System.gc();
 ​
         try {
             // 虚拟机参数-XX:+PrintGCDetails,输出gc信息
             Thread.sleep(5000);
         } catch (InterruptedException e) {
             e.printStackTrace();
         }
 ​
         //如果为空,代表被回收了
         if (salad.get() == null) {
             System.out.println("clear Apple。");
         }
     }
 }

执行结果

image-20220210235043657

构造方法二

 package com.example.demo.weakreference;
 ​
 import java.lang.ref.Reference;
 import java.lang.ref.ReferenceQueue;
 import java.lang.ref.WeakReference;
 ​
 public class Client2 {
     public static void main(String[] args) {
         ReferenceQueue<Apple> appleReferenceQueue = new ReferenceQueue<>();
         // new Apple("青苹果") 是被引用对象
         // appleWeakReference 是引用对象
         WeakReference<Apple> appleWeakReference = new WeakReference<>(new Apple("青苹果"),appleReferenceQueue);
         WeakReference<Apple> appleWeakReference2 = new WeakReference<>(new Apple("毒苹果"),appleReferenceQueue);
 ​
         System.out.println("GC调用前");
         Reference<? extends Apple> reference = null;
         while ((reference = appleReferenceQueue.poll())!=null){
             //不会输出,因为没有回收被弱引用的对象,并不会加入队列中
             System.out.println(reference);
         }
         System.out.println(appleWeakReference);
         System.out.println(appleWeakReference2);
         System.out.println(appleWeakReference.get());
         System.out.println(appleWeakReference2.get());
 ​
         System.out.println("=====调用gc=====");
         System.gc();
 ​
         try {
             Thread.sleep(5000);
         } catch (InterruptedException e) {
             e.printStackTrace();
         }
 ​
         System.out.println("=====gc调用后=====");
         System.out.println(appleWeakReference.get());
         System.out.println(appleWeakReference2.get());
         //输出结果,并且就是上面的appleWeakReference、appleWeakReference2,再次证明对象被回收了
         Reference<? extends Apple> reference2 = null;
         while ((reference2 = appleReferenceQueue.poll()) != null ) {
             //如果使用继承的方式就可以包含其他信息了
             System.out.println("appleReferenceQueue中:" + reference2);
         }
     }
 }

执行结果展示

image-20220210235221383

\