【问题标题】:Understanding WeakReferences理解弱引用
【发布时间】:2021-07-18 01:24:52
【问题描述】:

在下面的代码中...

public class MyObject {
    public static Map<String, WeakReference<MyObject>> cache = new HashMap<>();
    public static ReferenceQueue<MyObject> queue = new ReferenceQueue<>();
    public MyObject(String... args) {
        //define variables...
        cache.put(args[0], new WeakReference<>(this, queue));
    }
    // getters and setters
}

如果MyObjects 不断创建,由于cache 只包含弱引用,垃圾收集器最终会从cache 中删除项目吗?这些项目会变成null吗?有没有更好的缓存对象的方法?我的目标是存储不和谐的消息,这样我就不必再次获取它们。

【问题讨论】:

标签: java list hashmap garbage-collection weak-references


【解决方案1】:

WeakReferences(一旦被理解)并不神奇,甚至经常很容易被误用。一个这样的例子就是你的情况。首先声明一个 explicit ReferenceQueue&lt;MyObject&gt; 对你来说没什么用,这意味着你想“从这里和那里”推送代码以使其工作;这不是一个好策略。

一周参考的想法并不复杂。一旦 GC 循环发现某个实例被弱引用(存在对它的非强引用),它就可以简单地回收该内存并开始从 WeakReference::get 返回 null。以您的示例为例,当某些 MyObject 实例将被弱引用时,您的:

map.get("whatever").get()

将开始返回null。但Map.Entry 仍将出现在HashMap 中。没有自动魔法清理。即使WeakHashMap 也不是什么魔法。

有许多“其他”方式来缓存内容,如果没有更多细节,说起来很复杂,这将适合您的情况。有guava,最近使用的缓存,如LinkedHashMap等。

【讨论】:

    【解决方案2】:

    垃圾收集器最终会从缓存中删除项目吗?

    GC 最终会破坏引用,并将它们排入引用队列。

    它不会自动从地图中删除条目(引用损坏)。为此,您需要添加一些东西来使用参考队列并从地图中删除过时的条目。

    这些项目会变为空吗?

    见上文。 (不清楚你的意思……)

    有没有更好的缓存对象的方法?

    可能,使用WeakHashMap。它处理删除损坏的引用的问题。但打破参考的标准是不同的。在这种情况下,当发现 >>key

    另一种选择是使用使用 LinkedHashMap 实现的 LRU 缓存。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多