java中的四种引用
强引用>软引用>弱引用>虚引用
1、强引用
比如:
Object object = new Object();
就是强引用,垃圾回收的时候不会被回收掉,在内存不足的时候也不会被回收掉,会抛出OOM(Out of Memory)异常。
2、软引用
比如:
Object object = new Object()
SoftReference<Object> sf = new SoftReference<>(object);
在内存不足的时候发生垃圾回收就会被回收掉,然后软引用就会被放入引用队列里面,用来把占用的其他资源释放掉。
应用于缓存。(代码来源:https://blog.youkuaiyun.com/qq87034246/article/details/80710254 注释里面添加了自己的理解)
/**
* 整体的逻辑是使用软引用来存储某些对象,下次访问的时候直接在缓存里面寻找,增加访问的效率;
*
* 之所以使用软引用来实现缓存的原因是:一方面缓存是为了提高程序的运行速度,但是缓存并不是必须的,比如:当前程序正确运行的内存已经不够了,
* 缓存占的空间应该被回收掉,来保证程序正常运行。软引用的特性就是在内存不足的时候会被回收掉,这样就不会影响程序的正常运行,只不过下次程序运行
* 需要的资源需要重新读取进来,但是无伤大雅。
*/
public class Cache {
private Map<Object,ObjectRef> SoftCache;//用于cache内容的存储
private ReferenceQueue<Object> queue;//reference的队列
/**
创建一个私有弱引用的数据类,
再利用队列获得这个弱引用,
利用该弱引用清除缓存里仍然存在的键值对
就是弱引用对象没有了,就要把缓存里面对应的内容给删除,引用队列就是用来
删除map里面缓存的数据。
**/
private class ObjectRef extends SoftReference<Object>{
/**
ObjectRef继承了SoftReference,所以是一个软引用,软引用
要配合引用队列ReferenceQueue一起使用
**/
Object key;
public ObjectRef(Object key,Object value,ReferenceQueue<Object> queue) {
super(value,queue);
key = key;
}
}
/**
初始化SoftCache和queue
**/
public Cache(){
SoftCache = new HashMap<>();
queue = new ReferenceQueue<>();
}
/**
* 插入缓存数据
* @param key
* @param value
*/
public void set(Object key , Object value) {
//先清除已经被GC的软引用
cleanCache();
ObjectRef ref = new ObjectRef(key, value, queue);
SoftCache.put(key, ref);
}
/**
* 获取缓存数据
* @param value
*/
public Object get(Object value) {
ObjectRef ref = SoftCache.get(value);
if (ref == null) {
return null;
}
return ref.get();
}
/**
* 清除队列中无用引用,同时清除SoftCache中的无效关系(这里可以用WeakMap)
*/
private void cleanCache() {
ObjectRef ref = null;
while((ref= (ObjectRef) queue.poll())!=null){
SoftCache.remove(ref.key);
}
}
/**
* 清空缓存
*/
public void clear() {
cleanCache();
SoftCache.clear();
}
}
3、弱引用
无论内存是否足够,发生了垃圾回收就会被回收掉。
Object object = new Object()
WeakReference<Object> sf = new WeakReference<>(object);
4、虚引用
虚引用必须和队列一起使用,虚引用不能获得引用的对象,随时会被回收。
总结
- 引用队列的作用
队列就是为了在当前弱引用或者虚引用,引用的对象被销毁以后就会把弱引用或者虚引用放到引用队列里面,引用队列用来释放虚引用或者弱引用分别引用的对象关联的外部资源,垃圾回收释放的是对象时java内部资源,引用队列用来按顺序释放外部资源