WeakHashMap中有一个私有的expungeStaleEntries()方法,会在大部分共有方法中被调用。这个方法会将ReferenceQueue中所有失效的引用从Map中去除。


private void expungeStaleEntries() {
         Entry<K,V> e;
         while ( (e = (Entry<K,V>) queue.poll()) != null) {
             int h = e.hash;
             int i = indexFor(h, table.length);
 
             Entry<K,V> prev = table[i];
             Entry<K,V> p = prev;
             while (p != null) {
                 Entry<K,V> next = p.next;
                 if (p == e) {
                     if (prev == e)
                         table[i] = next;
                     else
                         prev.next = next;
                     e.next = null;  // Help GC
                     e.value = null; //  "   "
                     size--;
                     break;
                 }
                 prev = p;
                 p = next;
             }
         }
     }


  3、几个需要注意的地方

  WeakHashMap的Key是弱引用,Value不是。

  WeakHashMap不会自动释放失效的弱引用,仅当包含了expungeStaleEntries()的共有方法被调用的时候才会释放。

  4、一个简单的例子


public static void main(String args[]) {
         WeakHashMap<String, String> map = new WeakHashMap<String, String>();
         map.put(new String("1"), "1");
         map.put("2", "2");
         String s = new String("3");
         map.put(s, "3");
         while (map.size() > 0) {
             try {
                 Thread.sleep(500);
             } catch (InterruptedException ignored) {
             }
             System.out.println("Map Size:"+map.size());
             System.out.println(map.get("1"));
             System.out.println(map.get("2"));
             System.out.println(map.get("3"));
             System.gc();
         }
     }


  运行结果是:


Map Size:3
1
2
3
Map Size:2
null
2
3
Map Size:2
null
2
3
(一直循环)


  要注意String的特殊性,“2”是被放在常量池中的,所以没有被回收。