在以下代码段(其唯一目的是教育测试)中,contains()
始终为true。
Set<String> weakSet = Collections.newSetFromMap(new WeakHashMap<>());
weakSet.add("someKey");
System.gc();
weakSet.contains("someKey");
我希望由JVM完成的best effort回收空间包括删除只能弱访问的对象(弱集合元素,没有任何强引用)。但是我错了。
那么,有没有一种方法可以在实践中测试自动删除弱引用,以便您可以看到引用消失了?换句话说,如何使
contains()
返回false? 最佳答案
正如@Chai T.Rex在评论中正确提到的那样,字符串是垃圾收集的不好例子。要查看如何从弱集垃圾中收集对象,请尝试使用此修改后的代码版本:
Set<Object> weakSet = Collections.newSetFromMap(new WeakHashMap<>());
weakSet.add(new Object());
System.out.println(weakSet.size()); // prints "1"
while (weakSet.size() > 0)
System.gc();
System.out.println(weakSet.size()); // prints "0"
这里通常会发生什么:我们将新对象添加到集合(
weakSet.add(new Object())
)中。但是由于我们没有保留任何引用,GC会发现此对象将从集合中删除。需要在GC上循环,因为无法保证在这种简单示例情况下进行垃圾收集。