弱散列映射WeakHashMap

2018-06-18 00:16:03来源:未知 阅读 ()

新老客户大回馈,云服务器低至5折

WeakHashMap解决了什么问题?

  设计WeakHashMap类是为了解决一个有趣的问题。如果有一个值,对应的键已经不再使用了,将会出现什么情况呢?假定对某个键的最后一次引用已经消亡,不再有任何途径引用这个值的对象了。但是,由于在程序中的任何部分没有再出现这个键,所以,这个键/值对无法从映射中删除。为什么垃圾回收器不能够删除它呢?难道删除无用的对象不是垃圾回收器的工作吗?

  遗憾的是,事情没有这样简单。垃圾回收器跟踪活动的对象。只要映射对象是活动的,其中的所有桶也是活动的,它们不能被回收。因此,需要由程序负责从长期存活的映射表中删除那些无用的值。或者使用WeakHashMap完成这件事情。当对键的唯一引用来自散列条目时,这一数据结构将与垃圾回收器协同工作一起删除键/值对。

  下面是这种机制的内部运行情况。WeakHashMap使用弱引用(weak references)保存键。WeakReference对象将引用保存到另外一个对象中,在这里,就是散列键。对于这种类型的对象,垃圾回收器用一种特有的方式进行处理。通常,如果垃圾回收器发现某个特定的对象已经没有他人引用了,就将其回收。然而,如果某个对象只能由 WeakReference引用,垃圾回收器仍然回收它,但要将引用这个对象的弱引用放人队列中。WeakHashMap将周期性地检查队列,以便找出新添加的弱引用。一个弱引用进人队列意味着这个键不再被他人使用,并且已经被收集起来。于是,WeakHashMap将删除对应的条目。

摘自Java核心技术 卷1(第十版)

WeakHashMap回收测试

 1 @Test
 2     public void Test3() {
 3         String s1 = new String("s1");
 4         String s2 = new String("s2");
 5         String s3 = new String("s3");
 6         Map<String, Integer> map = new WeakHashMap<>();
 7         map.put(s1, 1);
 8         map.put(s2, 2);
 9         map.put(s3, 3);
10         map.forEach((K, V) -> System.out.println("GC回收前[" + K + ", " + V + "]"));
11         s2 = null;
12         System.gc();
13         System.out.println();
14         map.forEach((K, V) -> System.out.println("GC回收后[" + K + ", " + V + "]"));
15     }

输出结果:

GC回收前[s2, 2]
GC回收前[s1, 1]
GC回收前[s3, 3]

GC回收后[s1, 1]
GC回收后[s3, 3] 

 

注意:如果Key为字面量时,WeakHashMap回收机制失效。

例如:

 1 @Test
 2     public void Test4() {
 3         String s1 = "s1";
 4         String s2 = "s2";
 5         String s3 = "s3";
 6         Map<String, Integer> map = new WeakHashMap<>();
 7         map.put(s1, 1);
 8         map.put(s2, 2);
 9         map.put(s3, 3);
10         map.forEach((K, V) -> System.out.println("GC回收前[" + K + ", " + V + "]"));
11         s2 = null;
12         System.gc();
13         System.out.println();
14         map.forEach((K, V) -> System.out.println("GC回收后[" + K + ", " + V + "]"));
15     }

输出结果:

GC回收前[s2, 2]
GC回收前[s1, 1]
GC回收前[s3, 3]

GC回收后[s2, 2]
GC回收后[s1, 1]
GC回收后[s3, 3]

 

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:JDBC完美连接方法

下一篇:SpringMVC学习笔记之二(SpringMVC高级参数绑定)