Weak Reference Soft Reference Ph

2017-11-28  本文已影响0人  arnkore

JAVA 中的引用

JAVA 中存在4种引用,由强到弱依次是强引用、软引用、弱引用、虚引用。

软引用在实际中有重要的应用,例如浏览器的后退按钮。按后退时,这个后退按钮对应的网页内容是重新进行请求还是从缓存中取出呢?这就要看具体的实现策略了。

  1. 如果一个网页在浏览结束时就进行内容的回收,则按后退查看前面浏览过的页面时,需要重新请求构建。
  2. 如果将浏览过的网页存储到内存中可能会造成内存的大量浪费,甚至会造成内存溢出
    这时候就可以使用软引用。
Page prev = new Page(); // 获取页面进行浏览
SoftReference<Page> softRef = new SoftReference<Page>(prev); // 浏览完毕置为软引用
if (softRef.get() != null) {
   prev = softRef.get(); // 还没有被垃圾收集器回收,直接获取。
} else {
   prev = new Page(); // 由于内存吃紧,页面已被回收,重新构建。
   softRef = new SoftReference<Page>(prev); // 重新放进软引用
}

引用队列

实际上,WeakReference 有两个构造函数:

  1. WeakReference(T referent)
  2. WeakReference(T referent, ReferenceQueue<? super T> q)

我们可以看到第二个构造方法中提供了一个ReferenceQueue类型的参数,通过提供这个参数,我们便把创建的弱引用对象注册到这个引用队列上,这样当该弱引用对象被垃圾回收器回收时,就会把它插入到引用队列中,我们便可以对这些被清除的弱引用对象进行统一管理(一般是做资源清除工作)。

WeakHashMap

WeakHashMap 内部是通过弱引用来管理 entry 的,弱引用的特性对应到 WeakHashMap 上意味着什么呢?将一对 <key,value> 放入到 WeakHashMap 里并不能避免该 key 值被 GC 回收,除非在 WeakHashMap 之外还有对该key的强引用。

WeakHashMap的要点如下:

  1. 在 WeakHashMap 中,当某个键中的对象不再被正常使用时,将自动移除该条目。更精确地说,对于一个给定的键,其映射的存在并不阻止垃圾回收器对该键的丢弃,这就使该键成为可终止的,被终止,然后被回收。丢弃某个键时,其条目从映射中有效地移除。
  2. WeakHashMap 类的行为部分取决于垃圾回收器的动作。因为垃圾回收器在任何时候都可能丢弃键,WeakHashMap 就像是一个被悄悄移除条目的未知线程。特别地,即使对 WeakHashMap 实例进行同步,并且没有调用任何赋值方法,在一段时间后 size 方法也可能返回较小的值,对于 isEmpty 方法,可能先返回 false,然后返回true,对于给定的键,containsKey 方法可能先返回 true 然后返回 false,对于给定的键,get 方法可能先返回一个值,但接着返回 null,对于以前出现在映射中的键,put 方法返回 null,而 remove 方法返回 false,对于键集合、值集合和条目集合进行的检查,生成的元素数量会越来越少。
  3. WeakHashMap 中的每个键对象间接地存储为一个弱引用的指示对象。因此,不管是在映射内还是在映射之外,只有在垃圾回收器清除某个键的弱引用之后,该键才会自动移除。
  4. 类似于大多数的集合类,该类是并发不安全的,如果想要使用并发安全版本的 WeakHashMap,使用Collections.synchronizedMap(weakHashMap) 进行同步即可。

适用场景:
WeekHashMap 的这个特点特别适用于需要缓存的场景。在缓存场景下,由于内存是有限的,不能缓存所有对象;对象缓存命中可以提高系统效率,但缓存 MISS 也不会造成错误,因为可以通过计算重新得到。

上一篇 下一篇

猜你喜欢

热点阅读