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

posted on   Java面试365  阅读(58)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示