【问题标题】:How to wait until a WeakHashMap has updated?如何等到 WeakHashMap 更新?
【发布时间】:2021-11-02 20:29:13
【问题描述】:

除了固定超时之外,还有其他方法可以知道 WeakHashMap 在密钥变得弱可访问后何时更新其条目?

例如,这段代码使对键的强引用无效,除非添加超时,否则仍会打印条目在映射中。

    WeakHashMap<Integer, Integer> map = new WeakHashMap<>();
    Integer i = 1000;
    map.put(i, 1);
    System.out.println(map.size()); // prints 1
    i = null;
    System.gc();
    //Thread.sleep(0);
    System.out.println(map.size()); // without sleep prints 1, with sleep prints 0

有没有更优雅的方法可以知道 WeakReferences 何时完成更新?

【问题讨论】:

  • 你到底想做什么?
  • 以阻塞方式等待,直到 WeahHashMap 被更新并清除了 WeakReferenceKey
  • 是的,但为什么呢?你可能会永远等待。垃圾收集可能永远不会运行。

标签: java garbage-collection weak-references weakhashmap


【解决方案1】:

我认为没有什么好的方法可以做到这一点。有几个问题:

  1. WeakHashMap 中清除陈旧条目是一种内部机制,它涉及实现专用的ReferenceQueue。您需要打破封装才能访问 queue 字段。

    好吧,这是可能的,但理论上你会让你的代码特定于 Java 版本。

  2. 除了WeakHashMap 本身之外,没有什么好方法可以检查队列。 ReferenceQueue 仅提供三个公共操作:poll()remove()remove(time_out)。这些都会从队列中删除一个元素(如果有的话)。但如果 WeakHashMap 以外的任何内容删除了一个元素,则该元素将不会被处理。

    这实际上意味着如果不“破坏”队列,您就无法检测到队列中何时有东西。

    好的,这样你就可以打破ReferenceQueue 的抽象,并访问它的head 字段。

  3. 即使您执行上述操作,您仍然需要轮询 ReferenceQueue.head 字段以检测队列何时变为非空并再次为空。

  4. WeakHashMap 中处理队列的代码不会自发运行。 (没有更干净的线程。)它实际上在 WeakHashMap 上执行操作(例如 getputsizeclear 等)时运行。详细信息可能因版本而异。

    这意味着您的代码试图检测的“事件”只会在您调用get 时发生。因此,如果您只想在删除条目后调用get,那么您在时间依赖项中有一个“循环”。


最后,不能保证调用 System.gc() 会立即运行(或根本不会),或者它会检测给定的不可访问对象是不可访问的1 .即使它确实检测到这一点,也不能保证WeakReference 会及时被破坏。

因此,您不应将应用程序编码为依赖于这些东西……通过可预测的地图清理。 (如果这个只是单元测试的真正用例,我认为这不值得花时间在这上面。sleep 解决方法很好......假设它足够可靠。)

1 - 例如,如果对象已被永久保存并且System.gc() 调用仅触发次要收集,则对象不会被检测到为不可访问。

【讨论】:

  • 除上述之外,调用System.gc()不保证垃圾收集器立即运行。考虑到垃圾收集是一项非常昂贵的操作,由 JVM 来决定何时运行它。围绕垃圾收集制定逻辑似乎不是最好的主意。
  • 即使System.gc() 让 GC 运行,也不能保证单次 GC 运行会收集所有符合条件的对象。但更糟糕的是,Integer i = 1000; 行产生了一个未指定身份的对象。允许(甚至鼓励)运行时返回一个永远不会被收集的共享对象。或者具有不同 GC 策略的对象,例如在弱可达时不被收集。对于像WeakHashMapIdentityHashMap 这样的身份敏感映射,使用值类型的键通常不是一个好主意。结果可能……令人惊讶。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多