栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java中的弱引用WeakReference详解

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java中的弱引用WeakReference详解

最近再看ThreadLocal源码,其中内部类ThreadLocalMap中的Entry类继承了WeakReference,其表示key的ThreadLocal对象是通过弱应用指向,如果外部没有强引用对象指向ThreadLocal对象的时候就会被GC回收掉,不论当前的内存空间是否足够,这个对象都会被回收

一、WeakReference源码,其中只有两个构造函数
public class WeakReference extends Reference {
		//(1)
    public WeakReference(T referent) {
        super(referent);
    }
		//(2)
    public WeakReference(T referent, ReferenceQueue q) {
        super(referent, q);
    }

}
  • 构造函数(1)的参数referent就是弱引用指向的对象(弱引用和被弱引用指向的对象是两个不同的概念)
  • 构造函数(2)的参数比(1)多了一个ReferenceQueue,在对象被回收后会把弱引用对象,也就是WeakReference对象或者其子类的对象放入队列ReferenceQueue中,
二、验证弱引用对象被回收示例

定义PO类User:

public class User {
    private String username = "liming";
    private String password;
    private Job job;

    public Job getJob() {
        return job;
    }

    public void setJob(Job job) {
        this.job = job;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    protected void finalize() throws Throwable {
        super.finalize();
        System.out.println("User:"+username+ " finalize");
    }

    @Override
    public String toString() {
        return this.getUsername();
    }
}

定义弱引用对象UserWeakReference:

public class UserWeakReference extends WeakReference {

    public UserWeakReference(User user) {
        super(user);
    }

    public UserWeakReference(User user, ReferenceQueue q) {
        super(user, q);
    }
}

验证弱引用对象回收:

public class WeakReferenceTest {
    public static void main(String[] args) throws InterruptedException {
        //定义弱引用对象
        UserWeakReference reference = new UserWeakReference(new User());
        //输出弱应用对象
        System.out.println("Username:" + reference.get());
        //GC
        System.gc();
        Thread.sleep(5000);
        //输出GC后弱引用对象输出
        System.out.println(reference.get());
        //判定是否弱应用对象已被回收
        if (reference.get() == null) {
            System.out.println("user is clear...");
        }
    }
}

输出结果是:

Username:liming
User:liming finalize
null
user is clear...
三、验证ReferenceQueue队列的使用(基础类定义同上)
public class WeakReferenceQueueTest {
    public static void main(String[] args) throws InterruptedException {
        ReferenceQueue referenceQueue = new ReferenceQueue();
        UserWeakReference reference = new UserWeakReference(new User(), referenceQueue);
        //GC之前弱引用对象是否为空
        System.out.println("Username:" + reference.get());
        //GC回收之前ReferenceQueue是否为空
        System.out.println(referenceQueue.poll());
        System.gc();
        Thread.sleep(5000);
        //GC回收之后弱引用对象输出结果
        System.out.println(reference.get());
        //GC回收之后队列内容
        System.out.println(referenceQueue.poll());
        //GC之后判定ReferenceQueue是否为空
        if (referenceQueue.poll() != null) {
            System.out.println("referenceQueue is not null...");
        }
    }
}

输出结果:

Username:liming
null
User:liming finalize
null
com.emily.infrastructure.test.mainTest.UserWeakReference@1d057a39

可以看到在ReferenceQueue队列中在GC之前是空的,在GC之后是有弱引用对象存入队列之中。

GitHub地址:https://github.com/mingyang66/spring-parent

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/489545.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号