弱散列映射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]

 

转载于:https://www.cnblogs.com/mybdss/p/9160878.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值