ToB企服应用市场:ToB评测及商务社交产业平台

标题: 一文搞定WeakHashMap [打印本页]

作者: 来自云龙湖轮廓分明的月亮    时间: 前天 20:08
标题: 一文搞定WeakHashMap
写在前面

在缓存场景下,由于内存是有限的,不能缓存所有对象,因此就须要一定的删除机制,淘汰掉一些对象。这个时候可能很快就想到了各种Cache数据逾期策略,目前也有一些优秀的包提供了功能丰富的Cache,比如Google的Guava Cache,它支持数据定期逾期、LRU、LFU等策略,但它仍然有可能会导致有用的数据被淘汰,没用的数据迟迟不淘汰(如果策略利用适当的情况下这都是小概率事件)。
现在有种机制,可以让Cache里不用的key数据自动清算掉,用的还留着,不会出现误删除。而WeakHashMap 就实用于这种缓存的场景,由于它有自清算机制!
如果让你手动实现一种自清算的HashMap,可以怎么做?首先肯定是想办法先知道某个Key肯定没有在用了,然后清算掉HashMap中没有在用的对应的K-V。在JVM里一个对象没用了是指没有任何其他有用对象直接或者间接实行它,详细点就是在GC过程中它是GCRoots不可达的。而某个弱引用对象所指向的对象如果被判定为垃圾对象,Jvm会将该弱引用对象放到一个ReferenceQueue里,只须要看下这个Queue里的内容就知道某个对象另有没有用了。
WeakHashMap概述

从WeakHashMap名字也可以知道,这是一个弱引用的Map,当进行GC回收时,弱引用指向的对象会被GC回收。
WeakHashMap正是由于利用的是弱引用,因此它的对象可能被随时回收。更直观的说,当利用 WeakHashMap 时,即使没有显示的添加或删除任何元素,也可能发生如下情况:

从上图可以看出:
基本用法
  1. WeakHashMap < String, String > weakHashMap = new WeakHashMap < > (10);
  2. String key0 = new String("str1");
  3. String key1 = new String("str2");
  4. String key2 = new String("str3");
  5. // 存放元素
  6. weakHashMap.put(key0, "data1");
  7. weakHashMap.put(key1, "data2");
  8. weakHashMap.put(key2, "data3");
  9. System.out.printf("weakHashMap: %s\n", weakHashMap);
  10. // 是否包含某key
  11. System.out.printf("contains key str1 : %s\n", weakHashMap.containsKey(key0));
  12. System.out.printf("contains key str2 : %s\n", weakHashMap.containsKey(key1));
  13. // 移除key
  14. weakHashMap.remove(key0);
  15. System.out.printf("weakHashMap after remove: %s\n", weakHashMap);
  16. // 这意味着"弱键"key1再没有被其它对象引用,调用gc时会回收WeakHashMap中与key1对应的键值对
  17. key1 = null;
  18. // 内存回收,这里会回收WeakHashMap中与"key0"对应的键值对
  19. System.gc();
  20. try {
  21.     Thread.sleep(100);
  22. } catch (InterruptedException e) {
  23.     e.printStackTrace();
  24. }
  25. // 遍历WeakHashMap
  26. for (Map.Entry < String, String > m: weakHashMap.entrySet()) {
  27.     System.out.printf("next : %s >>> %s\n", m.getKey(), m.getValue());
  28. }
  29. // 打印WeakHashMap的实际大小
  30. System.out.printf("after gc WeakHashMap size: %s\n", weakHashMap.size());
复制代码
底层源码

构造器

[code]// 默认构造函数。WeakHashMap()// 指定“容量大小”的构造函数WeakHashMap(int capacity)// 指定“容量大小”和“加载因子”的构造函数WeakHashMap(int capacity, float loadFactor)// 包含“子Map”的构造函数WeakHashMap(Map




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4