什么是WeakHashMap--转
原文地址:http://laravel.iteye.com/blog/2303244
Java WeakHashMap 到底Weak在哪里,它真的很弱吗?WeakHashMap 的适用场景是什么,使用时需要注意些什么?弱引用和强引用对Java GC有什么不同影响?本文将给出清晰而简洁的介绍。
总体介绍
在Java集合框架系列文章的最后,笔者打算介绍一个特殊的成员:WeakHashMap,从名字可以看出它是某种 Map。它的特殊之处在于 WeakHashMap 里的entry
可能会被GC自动删除,即使程序员没有调用remove()
或者clear()
方法。
更直观的说,当使用 WeakHashMap 时,即使没有显示的添加或删除任何元素,也可能发生如下情况:
- 调用两次
size()
方法返回不同的值;- 两次调用
isEmpty()
方法,第一次返回false
,第二次返回true
;- 两次调用
containsKey()
方法,第一次返回true
,第二次返回false
,尽管两次使用的是同一个key
;- 两次调用
get()
方法,第一次返回一个value
,第二次返回null
,尽管两次使用的是同一个对象。
遇到这么奇葩的现象,你是不是觉得使用者一定会疯掉?其实不然,WeekHashMap 的这个特点特别适用于需要缓存的场景。在缓存场景下,由于内存是有限的,不能缓存所有对象;对象缓存命中可以提高系统效率,但缓存MISS也不会造成错误,因为可以通过计算重新得到。
要明白 WeekHashMap 的工作原理,还需要引入一个概念:弱引用(WeakReference)。我们都知道Java中内存是通过GC自动管理的,GC会在程序运行过程中自动判断哪些对象是可以被回收的,并在合适的时机进行内存释放。GC判断某个对象是否可被回收的依据是,是否有有效的引用指向该对象。如果没有有效引用指向该对象(基本意味着不存在访问该对象的方式),那么该对象就是可回收的。这里的“有效引用”并不包括弱引用。也就是说,虽然弱引用可以用来访问对象,但进行垃圾回收时弱引用并不会被考虑在内,仅有弱引用指向的对象仍然会被GC回收。
WeakHashMap 内部是通过弱引用来管理entry
的,弱引用的特性对应到 WeakHashMap 上意味着什么呢?将一对key, value
放入到 WeakHashMap 里并不能避免该key
值被GC回收,除非在 WeakHashMap 之外还有对该key
的强引用。
关于强引用,弱引用等概念以后再具体讲解,这里只需要知道Java中引用也是分种类的,并且不同种类的引用对GC的影响不同就够了。
具体实现
WeakHashMap的存储结构类似于HashMap,读者可自行参考前文,这里不再赘述。
关于强弱引用的管理方式,博主将会另开专题单独讲解。
Weak HashSet?
如果你看过前几篇关于 Map 和 Set 的讲解,一定会问:既然有 WeekHashMap,是否有 WeekHashSet 呢?答案是没有:( 。不过Java Collections工具类给出了解决方案,Collections.newSetFromMap(Map<E,Boolean> map)
方法可以将任何 Map包装成一个Set。通过如下方式可以快速得到一个 Weak HashSet:
Set<Object> weakHashSet = Collections.newSetFromMap(
new WeakHashMap<Object, Boolean>());
不出你所料,newSetFromMap()
方法只是对传入的 Map做了简单包装:
public static <E> Set<E> newSetFromMap(Map<E, Boolean> map) {
return new SetFromMap<>(map);
}
private static class SetFromMap<E> extends AbstractSet<E>
implements Set<E>, Serializable
{
private final Map<E, Boolean> m; // The backing map
private transient Set<E> s; // Its keySet
SetFromMap(Map<E, Boolean> map) {
if (!map.isEmpty())
throw new IllegalArgumentException("Map is non-empty");
m = map;
s = map.keySet();
}
public void clear() { m.clear(); }
public int size() { return m.size(); }
public boolean isEmpty() { return m.isEmpty(); }
public boolean contains(Object o) { return m.containsKey(o); }
public boolean remove(Object o) { return m.remove(o) != null; }
public boolean add(E e) { return m.put(e, Boolean.TRUE) == null; }
public Iterator<E> iterator() { return s.iterator(); }
public Object[] toArray() { return s.toArray(); }
public <T> T[] toArray(T[] a) { return s.toArray(a); }
public String toString() { return s.toString(); }
public int hashCode() { return s.hashCode(); }
public boolean equals(Object o) { return o == this || s.equals(o); }
public boolean containsAll(Collection<?> c) {return s.containsAll(c);}
public boolean removeAll(Collection<?> c) {return s.removeAll(c);}
public boolean retainAll(Collection<?> c) {return s.retainAll(c);}
// addAll is the only inherited implementation
}
什么是WeakHashMap--转的更多相关文章
- java弱引用之WeakHashMap相关资料
本人博客中有一篇文章对java中的引用有详细的介绍[http://www.cnblogs.com/javaee6/p/4763190.html],java中WeakHashMap这个类就是java弱引 ...
- Map接口,Map.Entry,hashMap类,TreeMap类,WeakHashMap。
Collection接口之前接触过,每次保存的对象是一个对象,但是在map中保存的是一对对象,是以key->value形式保存的. 定义: public interface Map<K,V ...
- WeakHashMap回收时机
import java.util.ArrayList; import java.util.List; import java.util.WeakHashMap; public class TestWe ...
- Java魔法堂:四种引用类型、ReferenceQueue和WeakHashMap
一.前言 JDK1.2以前只提供一种引用类型——强引用 Object obj = new Object(); .而JDK1.2后我们多另外的三个选择分别是软引用 java.lang.ref.SoftR ...
- 容器--WeakHashMap
一.概述 WeakHashMap是Map的一种,根据其类的命令可以知道,它结合了WeakReference和HashMap的两种特点,从而构造出了一种Key可以自动回收的Map. 前面我们已经介绍了W ...
- Java 集合系列13之 WeakHashMap详细介绍(源码解析)和使用示例
概要 这一章,我们对WeakHashMap进行学习.我们先对WeakHashMap有个整体认识,然后再学习它的源码,最后再通过实例来学会使用WeakHashMap.第1部分 WeakHashMap介绍 ...
- 不正确使用WeakHashMap引起的卡死
公司的jenkins今天出了一点问题,起来以后,总是处于等待状态,所有的任务无法正常加载.登陆界面也出不了.而且cpu占用率100% 把线程导出来,看到: “Loading job NMS_Patch ...
- Java 集合系列14之 Map总结(HashMap, Hashtable, TreeMap, WeakHashMap等使用场景)
概要 学完了Map的全部内容,我们再回头开开Map的框架图. 本章内容包括:第1部分 Map概括第2部分 HashMap和Hashtable异同第3部分 HashMap和WeakHashMap异同 转 ...
- 浅谈WeakHashMap
Java WeakHashMap 到底Weak在哪里,它真的很弱吗?WeakHashMap 的适用场景是什么,使用时需要注意些什么?弱引用和强引用对Java GC有什么不同影响?本文将给出清晰而简洁的 ...
- Java中关于WeakReference和WeakHashMap的理解
新美大的10月11日的笔试中有一道选择题,让选择函数返回结果,代码如下: private static String test(){ String a = new String("a&quo ...
随机推荐
- ABP框架详解(七)Caching
在ABP框架中存在一个缓存机制,使用ICache的继承类来存储最终需要缓存的数据,可以吧ICache看成一个字典对象,使用Key作为真实数据的具有唯一性的表示.使用上与字典对象完全相同,Get方法传递 ...
- Runtime消息传送
person.h #import<Foundation/Foundation.h> @interfacePerson :NSObject + (void)eat; - (void)run: ...
- Ubuntu Tftpd服务配置
---恢复内容开始--- 服务器端(ip:192.168.1.100) #安装tftpd-hpa sudo apt-get install tftpd-hpa 修改配置文件 sudo vim /etc ...
- Visual Studio Xamarin编译Android项目出错的解决办法
安装完Xamarin后,编译Android项目时,你会发现好长时间进度都不动,当你取消编译后,会发现其实是出错了,就是因在Android项目在第一次编译时要去google网站上下一个andorid s ...
- dojo/io-query源码解析
该模块主要对url中的query部分进行处理,我们发送GET请求时,将参数直接放在URL中,经常碰到的需求就是把一个对象转化为query字符串放到url中去发送GET请求.io-query模块便提供了 ...
- drag & resize元素的jQuery实现
有时项目中会遇到需要拖动元素.拖拽调整元素大小的需求.大部分时候都不想自己写一遍,因为已经有很多现成的例子了.例如jqueryui提供的drag和resize.但是仅仅是为了这么小一个功能就引入一个库 ...
- C#Light Everywhere
C#语法嵌入式脚本,0.1Beta版本咯,可用于各种环境,欢迎测试. 可以解决各种热更新问题 比如Unity在AOT环境下,比如各种不能采用动态加载DLL的场合. 如果遇到bug,请给我留言,我会从速 ...
- C#开源磁盘/内存缓存引擎
前言 昨天写了个 <基于STSdb和fastJson的磁盘/内存缓存>,大家可以先看看.下午用到业务系统时候,觉得可以改进一下,昨晚想了一个晚上,刚才重新实现一下. 更新 1. 增加了对批 ...
- 数据库的Timeout
数据库的Timeout 其实有很多种情况. 一个是执行的超时时间 executionTimeOut,一个是连接的超时时间connectionTimeOut, 还有呢? 等待的超时时间 ReadTime ...
- PowerDesigner实用操作
1. 让PhysicalDiagram里的表显示字段名Tools→Display Preferences→在General Settings里选择Table→点击Advanced→选择Form下的Co ...