弱散列映射WeakHashMap

Posted mybdss

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了弱散列映射WeakHashMap相关的知识,希望对你有一定的参考价值。

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]

 








以上是关于弱散列映射WeakHashMap的主要内容,如果未能解决你的问题,请参考以下文章

数据结构 - WeakHashMap

Java中的集合 实现Map接口的WeakHashMap

Java中的集合 实现Map接口的WeakHashMap

WeakHashMap和HashMap的区别

散列 torrent 文件片段

基于散列片段的安全性究竟是如何工作的?