本日一起来看下java.util包里的WeakHashMap东西类。
WeakHashMap的界说如下:
public class WeakHashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>
简朴来说,WeakHashMap实现了Map接口,基于hash-table实现,在这种Map中,昆山软件开发,key的范例是WeakReference。假如对应的key被接纳,则这个key指向的工具会被从Map容器中移除。
WeakHashMap跟普通的HashMap差异,WeakHashMap的行为必然水平上基于垃圾收集器的行为,因此一些Map数据布局对应的知识在WeakHashMap上会失效——size()要领的返回值会跟着措施的运行变小,isEmpty()要领的返回值会从false酿成true等等。
强引用、软引用和弱引用
“引用”,在Java中指的是一个工具对另一工具的利用(指向)。WeakHashMap中的键的范例是WeakReference,在Java中尚有别的两种引用:强引用(Strong Reference)、软引用(Soft Reference)。
强引用
被强引用指向的工具,绝对不会被垃圾收集器接纳。Integer prime = 1;
,这个语句中prime工具就有一个强引用。
软引用
被SoftReference指向的工具大概会被垃圾收集器接纳,可是只有在JVM内存不足的环境下才会接纳;如下代码可以建设一个软引用:
Integer prime = 1; SoftReference<Integer> soft = new SoftReference<Integer>(prime); prime = null;
弱引用
当一个工具仅仅被WeakReference引用时,在下个垃圾收集周期时候该工具就会被接纳。我们通过下面代码建设一个WeakReference:
Integer prime = 1; WeakReference<Integer> soft = new WeakReference<Integer>(prime); prime = null;
当把prime赋值为null的时候,原prime工具会在下一个垃圾收集周期中被接纳,因为已经没有强引用指向它。
操作WeakHashMap实现内存缓存
可以看出,WeakHashMap的这种特性较量适合实现雷同当地、堆内缓存的存储机制——缓存的失效依赖于GC收集器的行为。假设一种应用场景:我们需要生存一批大的图片工具,个中values是图片的内容,key是图片的名字,这里我们需要选择一种符合的容器生存这些工具。
利用普通的HashMap并不是好的选择,这些大工具将会占用许多内存,而且还不会被GC接纳,昆山软件开发,除非我们在对应的key废弃之前主动remove掉这些元素。WeakHashMap很是适合利用在这种场景下,下面的代码演示了详细的实现:
WeakHashMap<UniqueImageName, BigImage> map = new WeakHashMap<>(); BigImage bigImage = new BigImage("image_id"); UniqueImageName imageName = new UniqueImageName("name_of_big_image"); //强引用 map.put(imageName, bigImage); assertTrue(map.containsKey(imageName)); imageName = null; //map中的values工具成为弱引用工具 System.gc(); //主动触发一次GC await().atMost(10, TimeUnit.SECONDS).until(map::isEmpty);
首先,建设一个WeakHashMap工具来存储BigImage实例,对应的key是UniqueImageName工具,生存到WeakHashMap里的时候,key是一个弱引用范例。
然后,我们将imageName配置为null,这样就没有其他强引用指向bigImage工具,凭据WeakHashMap的法则,在下一次GC周期中会接纳bigImage工具。
通过System.gc()
主动触发一次GC进程,劳务派遣管理系统,然后可以发明WeakHashMap成为空的了。
总结
本文从WeakHashMap的界说讲起,又通过先容Java中的三种引用范例来领略WeakHashMap的事情道理,最后操作一个存储大工具的例子演示了WeakHashMap的应用场景。本文中提到的代码,可以在GitHub工程看到。
参考资料