【问题标题】:Is there a way to test when an element is removed from a weak set?有没有办法测试何时从弱集中删除元素?
【发布时间】:2017-01-31 23:02:19
【问题描述】:

在下面的 sn-p(其唯一目的是教育测试)中,contains() 始终 ↲ 为真。

    Set<String> weakSet = Collections.newSetFromMap(new WeakHashMap<>());
    weakSet.add("someKey");
    System.gc();
    weakSet.contains("someKey");

我希望 JVM 为回收空间所做的 best effort 包括删除只能弱可达的对象(没有任何强引用的弱集合元素)。但我错了。

那么,有没有办法在实践中测试弱引用的自动删除,这样你就可以看到引用消失了?换句话说,如何让contains() 返回 false?

【问题讨论】:

标签: java weak-references


【解决方案1】:

正如@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,因为无法保证在这个简单的示例案例中进行垃圾收集。

【讨论】:

  • 绝对是答案。感谢赐教!
  • …或者你把原代码的第二行改成weakSet.add(new String("someKey"));
  • @Holger,好主意。但它似乎不太直观。
  • 好吧,它演示了为什么基于身份的语义(如实例可达性)不能很好地与相等语义(我有一个对等对象/字符串的引用,但它是否被报告在集合,取决于 other 对象的构造方式)
猜你喜欢
  • 2011-02-23
  • 2012-01-12
  • 1970-01-01
  • 2020-07-16
  • 2017-09-14
  • 1970-01-01
  • 2020-08-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多