WeakReference弱引用

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值