import java.io.*; import java.util.*; import java.lang.ref.*; public class Test { //Run this as "java -verbosegc -Xmx1m -Xms1m Test" //However the 1.2 JVM crashes the main thread when I flush the memory //and puts the GC thread into a loop if you use -verbosegc //So use only the 1.3 JVM. public static void main(String[] args) { test(); } static Object DUMMY_OBJ = new Object(); public static void test() { String key = new String("hi"); String value = "xyz"; String equalKey = new String("hi"); //construction WeakHashMap aWeakHashMap = new WeakHashMap(); HashMap aHashMap = new HashMap(); ReferenceQueue Queue = new ReferenceQueue(); //update aWeakHashMap.put(key, value); MyWeakReference RefKey = new MyWeakReference(key, Queue); aHashMap.put(RefKey, value); System.out.println(RefKey.get() == key); //access System.out.println(aWeakHashMap.get(equalKey) == value); System.out.println(aWeakHashMap.get(key) == value); MyWeakReference RefKey2 = new MyWeakReference(equalKey, Queue); System.out.println(aHashMap.get(RefKey2) == value); System.out.println(aHashMap.get(RefKey) == value); //force gc of the weakly held key key = null; flushMemory(); System.out.println(RefKey.get() == null); //Access again System.out.println(aWeakHashMap.get(equalKey) == null); MyWeakReference RefKey3 = new MyWeakReference(equalKey, Queue); System.out.println(aHashMap.get(RefKey3) == null); //Process ref objs aWeakHashMap.put(DUMMY_OBJ, DUMMY_OBJ); MyWeakReference aRef; while ((aRef = (MyWeakReference) Queue.poll()) != null) { System.out.println(aRef == RefKey); aHashMap.remove(aRef); } } public static void flushMemory() { Vector v = new Vector(); int count = 0; int size = 1048576; while(size > 1) { try { for (; true ; count++) { v.addElement( new byte[size] ); } } catch(OutOfMemoryError bounded){size = size/2;} } v = null; //release for GC v = new Vector(); } } class MyWeakReference extends WeakReference { //We need to store the hash code separately since the referent //could be removed by the GC. int hash; public MyWeakReference(Object o, ReferenceQueue q) { super(o,q); hash = o.hashCode(); } public int hashCode() { return hash; } public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof MyWeakReference)) return false; Object t = this.get(); Object u = ((MyWeakReference)o).get(); if ((t == null) || (u == null)) return false; if (t == u) return true; return t.equals(u); } }