WeakHashMap理解
WeakHashMap实现了Map接口,是HashMap的一种实现,他使用弱引用作为内部数据的存储方案,WeakHashMap可以作为简单缓存表的解决方案,当系统内存不够的时候,垃圾收集器会自动的清除没有在其他任何地方被引用的键值对。
如果需要用一张很大的HashMap作为缓存表,那么可以考虑使用WeakHashMap,当键值不存在的时候添加到表中,存在即取出其值。
1 2 3 4 5 | WeakHashMap weakMap = new WeakHashMap<Integer, byte []>(); for ( int i = 0 ; i < 10000 ; i++){ Integer ii = new Integer(i); weakMap.put(ii, new byte [i]); } |
1 2 3 4 5 | HashMap map = new HashMap<Integer, byte []>(); for ( int i = 0 ; i < 10000 ; i++) { Integer ii = new Integer(i); map.put(ii, new byte [i]); } |
这2段代码分别用-Xmx5M的参数运行,运行的结果是第一段代码可以很好的运行,第二段代码会出现“Java Heap Space”的错误,这说明用WeakHashMap存储,在系统内存不够用的时候会自动回收内存。
如果WeakHashMap的key在系统内持有强引用,那么WeakHashMap就退化为HashMap,所有的表项无法被垃圾收集器自动清理。

1 package com.froest.excel; 2 3 import java.util.Iterator; 4 import java.util.Map; 5 import java.util.WeakHashMap; 6 7 public class Test5 { 8 9 /** 10 * @param args 11 */ 12 public static void main(String[] args) { 13 // TODO Auto-generated method stub 14 WeakHashMap<AA, People1> weakMap1 = new WeakHashMap<AA, People1>(); 15 String b = new String("louhang1"); 16 AA a = new AA(b); 17 BB bb = new BB(a); 18 People1 p1 = new People1(bb); 19 weakMap1.put(p1.getB().getAA(), p1); 20 p1.getB().setAA(null);// 去除对象a的强引用 21 a = null;// 去除对象a的强引用,并让垃圾收集器回收AA对象在堆中的内存 22 System.gc(); 23 Iterator i = weakMap1.entrySet().iterator(); 24 while (i.hasNext()) { 25 Map.Entry en = (Map.Entry) i.next(); 26 System.out.println("weakMap:" + en.getKey() + ":" + en.getValue()); 27 } 28 } 29 } 30 31 class AA { 32 private String a; 33 34 public AA(String a) { 35 this.a = a; 36 } 37 38 public String getA() { 39 return a; 40 } 41 42 public void setA(String a) { 43 this.a = a; 44 } 45 } 46 47 class BB { 48 private AA a; 49 50 public BB(AA a) { 51 this.a = a; 52 } 53 54 public AA getAA() { 55 return a; 56 } 57 58 public void setAA(AA a) { 59 this.a = a; 60 } 61 } 62 63 class People1 { 64 private BB b; 65 66 public People1(BB b) { 67 this.b = b; 68 } 69 70 public BB getB() { 71 return b; 72 } 73 74 public void setB(BB b) { 75 this.b = b; 76 } 77 }
运行上面代码以后没有输出任何结果,说明,WeakHashMap中的键值对已经被回收了,如果注释掉p1.getB().setAA(null);或者a = null;这2行中的任意一行都没法清除WeakhashMap中的键值对。
在WeakHashMap的get(),put()函数中的getTable()方法会调用expungeStateEntries方法,以清理持有弱引用的key的表项。exPungeStateEntries方法源代码:

1 private void expungeStaleEntries() { 2 Entry<K,V> e; 3 while ( (e = (Entry<K,V>) queue.poll()) != null) { 4 int h = e.hash; 5 int i = indexFor(h, table.length); 6 7 Entry<K,V> prev = table[i]; 8 Entry<K,V> p = prev; 9 while (p != null) { 10 Entry<K,V> next = p.next; 11 if (p == e) { 12 if (prev == e) 13 table[i] = next; 14 else 15 prev.next = next; 16 e.next = null; // Help GC 17 e.value = null; // " " 18 size--; 19 break; 20 } 21 prev = p; 22 p = next; 23 } 24 } 25 }
在第二个while循环中会移除已经被回收的表项。
扬帆起航,生命正式从这里开始...
爱情终将消失于茫茫的时间洪流之中,沉淀于厚重的黄泥沙丘之下...
爱情终将消失于茫茫的时间洪流之中,沉淀于厚重的黄泥沙丘之下...
分类:
j2se
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:使用Catalyst进行自然语言处理
· 分享一个我遇到过的“量子力学”级别的BUG。
· Linux系列:如何调试 malloc 的底层源码
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 几个技巧,教你去除文章的 AI 味!
· 系统高可用的 10 条军规
· 关于普通程序员该如何参与AI学习的三个建议以及自己的实践
· 对象命名为何需要避免'-er'和'-or'后缀
· 使用Avalonia/C#构建一个简易的跨平台MCP客户端