zoukankan      html  css  js  c++  java
  • WeakHashMap理解

      WeakHashMap实现了Map接口,是HashMap的一种实现,他使用弱引用作为内部数据的存储方案,WeakHashMap可以作为简单缓存表的解决方案,当系统内存不够的时候,垃圾收集器会自动的清除没有在其他任何地方被引用的键值对。

      如果需要用一张很大的HashMap作为缓存表,那么可以考虑使用WeakHashMap,当键值不存在的时候添加到表中,存在即取出其值。

         WeakHashMap weakMap = new WeakHashMap<Integer, byte[]>();
         for(int i = 0; i < 10000; i++){
         Integer ii = new Integer(i);
         weakMap.put(ii, new byte[i]);
         }
    

      

        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 }
    View Code

      运行上面代码以后没有输出任何结果,说明,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     }
    View Code

     在第二个while循环中会移除已经被回收的表项。

  • 相关阅读:
    webpack(二)
    webpack(一)
    初探Vue SSR(1)
    Node版本管理控制器n
    Gitlab用户在组中有五种权限:Guest、Reporter、Developer、Master、Owner
    微信小程序分享参数传递
    关于vue-cli3.*搭建项目遇到问题整理
    请求头出现provisional headers are shown 和 vue-cli 3.x配置跨域代理
    HDU6409 没有兄弟的舞会
    HDU6446 Tree and Permutation
  • 原文地址:https://www.cnblogs.com/God-froest/p/weakHashMap.html
Copyright © 2011-2022 走看看