热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

java强软弱虚_JAVA:强、软、弱、虚引用的区别和使用

引用队列(ReferenceQueue)作用Queue的意义在于我们在外部可以对queue中的引用进行监控,当引用中的对象被回收后,我们可以对引用对象本

引用队列(ReferenceQueue)作用

Queue的意义在于我们在外部可以对queue中的引用进行监控,当引用中的对象被回收后,我们可以对引用对象本身继续做一些清理操作,因为我们引用对象(softRef)也占有一定的资源。

弱引用(WeakReference)

弱引用中的对象具有很短的声明周期,因为在系统GC时,只要发现弱引用,不管堆空间是否足够,都会将对象进行回收。由于垃圾回收器是一个优先级很低的线程,因此不一定会很快发现那些只具有弱引用的对象。

弱引用的简单使用:

Object obj = new Object();

WeakReference weakRef = new WeakReference(obj);

//删除强引用

obj = null;

System.out.println("gc之后的值:" + weakRef.get()); // 对象依然存在

//调用gc

System.gc();

System.out.println("gc之后的值:" + weakRef.get()); // 对象为null

弱引用也可以和一个引用队列联合使用,如果弱引用中的对象(obj)被回收,那么软引用会被 JVM 加入关联的引用队列中。

ReferenceQueue queue &#61; new ReferenceQueue<>();

Object obj &#61; new Object();

WeakReference weakRef &#61; new WeakReference(obj,queue);

//删除强引用

obj &#61; null;

System.out.println("gc之后的值: " &#43; weakRef.get()); // 对象依然存在

//调用gc

System.gc();

//如果obj被回收&#xff0c;则软引用会进入引用队列

Reference> reference &#61; queue.remove();

if (reference !&#61; null){

System.out.println("对象已被回收: "&#43; reference.get());  // 对象为null

}

软引用和弱引用都非常适合保存那些可有可无的缓存数据&#xff0c;当内存不足时&#xff0c;缓存数据被回收(再通过备选方案查询)&#xff0c;当内存充足时&#xff0c;也可以存在较长时间&#xff0c;起到加速的作用。

应用

WeakHashMap

当key只有弱引用时&#xff0c;GC发现后会自动清理键和值&#xff0c;作为简单的缓存表解决方案。

ThreadLocal

ThreadLocal.ThreadLocalMap.Entry 继承了弱引用&#xff0c;key为当前线程实例&#xff0c;和WeakHashMap基本相同。

虚引用(PhantomReference)

虚引用 就是 形同虚设 &#xff0c;它并不能决定 对象的生命周期。任何时候这个只有虚引用的对象都有可能被回收。因此&#xff0c;虚引用主要用来跟踪对象的回收&#xff0c;清理被销毁对象的相关资源。PhantomReference的 get() 方法永远返回null &#xff0c;而且只提供了与引用队列同用的构造函数。所以虚引用必须和引用队列一同使用。

Map map &#61; new HashMap<>();

ReferenceQueue queue &#61; new ReferenceQueue<>();

Object obj &#61; new Object();

PhantomReference phantomRef &#61; new PhantomReference(obj,queue);

map.put(obj,"obj val");

new CheckRefQueue(queue,map).start();

//删除强引用

obj &#61; null;

Thread.sleep(1000);

int i &#61; 1;

while (true){

System.out.println("第"&#43;i&#43;"次gc");

System.gc();

Thread.sleep(1000);

}

public class CheckRefQueue extends Thread {

private ReferenceQueue queue;

private Map map;

public CheckRefQueue(ReferenceQueue queue, Map map) {

this.queue &#61; queue;

this.map &#61; map;

}

&#64;Override

public void run() {

// 等待&#xff0c;直到对象呗回收

Reference reference &#61; queue.remove();

// 释放引用对象的引用

map.remove(reference.get());

}

}

总结

e7cab0177a3e57b203af09de5df24fdc.png

reference-level.png

作者&#xff1a;码上实战

链接&#xff1a;https://www.jianshu.com/p/ee4363989022

来源&#xff1a;简书

著作权归作者所有。商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处。



推荐阅读
author-avatar
嘻嘻嘻嘻
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有