Java中的WeakHashMap会自动把键包装为WeakReference。WeakReference,即弱引用,是java中定义的四种引用之一,被WeakReference引用的对象会在下次GC操作中被回收。因此,将<键,值>放入WeakHashMap后,下次垃圾回收时该键会被自动丢弃,丢弃某个键后,其关联的值对象也会被丢弃。但要注意:值对象不能直接或间接地引用其自身的键,否则阻止键的丢弃。
下面的代码测试了WeakHashMap中的对象在下次GC操作中被回收,当值对象引用了键对象时,则不会被回收。
/**
* 测试WeakHashMap与垃圾收集情况!
* VM参数:-XX:+PrintGCDetails
* @author
*
*/
public class TestWeakHashMap {
private WeakHashMap<ClassA, ClassB> map = new WeakHashMap<ClassA, ClassB>();
/* objA和objB对象可以被回收 */
private void test() {
ClassA objA = new ClassA();
ClassB objB = new ClassB();
map.put(objA, objB);
}
/* objA和objB对象无法被回收 */
private void testNoGC() {
ClassA objA = new ClassA();
ClassB objB = new ClassB(objA);
map.put(objA, objB);
}
static class ClassA {
byte[] bArray = new byte[1024 * 1024];
}
static class ClassB {
ClassA a;
public ClassB() {}
public ClassB(ClassA a) {
this.a = a;
}
}
public static void main(String[] args) {
TestWeakHashMap testObj = new TestWeakHashMap();
// testObj.test();
testObj.testNoGC();
System.gc();
}
}
运行test(),输出如下,可以看到键、值对象都被回收了:
[Full GC (System) [Tenured: 0K->365K(10944K), 0.0067549 secs] 1627K->365K(15872K), [Perm : 126K->126K(12288K)], 0.0068349 secs]
运行testNoGC(),输出如下,由于值对象中存在键的映射,因此阻止了键的回收,所以键值对象继续位于内存中:
[Full GC (System) [Tenured: 0K->1389K(10944K), 0.0105601 secs] 1627K->1389K(15872K), [Perm : 126K->126K(12288K)], 0.0106601 secs]