2

我有一个测试应用程序,其中包含一个存储地图的类和一个调用该类方法的按钮:

Map<Object, Object> weakMap = new WeakHashMap<Object, Object>();

该按钮执行此操作:

public void fillWeakHashMap(int size) {
    List<String> createObjects = (List<String>) createObject(size);
    for (Object ob : createObjects) {
        weakMap.put(ob, ob);
    }
}

因此,带有地图的主类仍然存在,但我放入它的对象是在单独的方法中创建的,因为它是一个WeakHashMap我认为从方法退出后fillWeakHashMap,地图中的键/对象将被 GC 清除。

我打开 VisualVM->VisualGC 并单击 Monitor->PerformGC 10 次,旧空间几乎已满,这意味着 GC 没有清除这些对象。那么我做错了什么?

4

2 回答 2

9

WeakHashMap 的 javadoc 的第一句话

Map 接口的基于哈希表的实现,带有弱键。WeakHashMap 中的条目在其键不再常用时将被自动删除。更准确地说,给定键的映射的存在不会阻止该键被垃圾收集器丢弃,也就是说,使其可终结,最终确定,然后回收。当一个键被丢弃时,它的条目被有效地从映射中删除,所以这个类的行为与其他映射实现有些不同。

再往下一点,它写道:

WeakHashMap 中的值对象由普通的强引用保存。因此,应注意确保值对象不会直接或间接地强烈引用它们自己的键,因为这将防止键被丢弃。

也就是说,只有键被弱引用,而值被强引用。在您的代码中,每个键也使用一个值,因此被强烈引用,因此不会被垃圾收集。

于 2015-05-02T15:20:01.250 回答
1

您为地图中的每个对象保留一个引用,例如 ob 仍然引用自身,这就是为什么没有清除任何内容,因为 GC 不能声称这些对象没有被使用并且可以被清除。

于 2015-05-02T15:19:14.397 回答