Java 你什么时候会使用WeakHashMap或WeakReference?

Java 你什么时候会使用WeakHashMap或WeakReference?,java,weak-references,Java,Weak References,弱引用的使用是我从未见过的实现,所以我试图找出它们的用例是什么,以及实现将如何工作。您何时需要使用WeakHashMap或WeakReference以及如何使用它?例如,如果您希望跟踪某个类创建的所有对象。为了仍然允许对这些对象进行垃圾收集,您需要保留对对象的弱引用列表/映射,而不是对象本身 现在如果有人能向我解释幻觉,我会很高兴 强引用的一个问题是 缓存,特别是非常大的 像图像这样的结构。假设你 有一个必须工作的应用程序 使用用户提供的图像,如 网站设计工具,我的工作。 当然,您希望缓存这些

弱引用的使用是我从未见过的实现,所以我试图找出它们的用例是什么,以及实现将如何工作。您何时需要使用
WeakHashMap
WeakReference
以及如何使用它?

例如,如果您希望跟踪某个类创建的所有对象。为了仍然允许对这些对象进行垃圾收集,您需要保留对对象的弱引用列表/映射,而不是对象本身

现在如果有人能向我解释幻觉,我会很高兴

强引用的一个问题是 缓存,特别是非常大的 像图像这样的结构。假设你 有一个必须工作的应用程序 使用用户提供的图像,如 网站设计工具,我的工作。 当然,您希望缓存这些 图像,因为从磁盘加载它们 很贵,你想买吗 避免有两个的可能性 副本(可能巨大) 立即将图像存储在内存中

因为图像缓存应该是 防止我们在需要时重新加载图像 我们绝对不需要,你会的 快速意识到缓存应该 始终包含对任何 已在内存中的图像。具有 不过,普通的强引用, 该引用本身将迫使 要保留在内存中的图像 需要您以某种方式确定何时 在中不再需要该图像 内存并将其从缓存中删除, 这样它就有资格 垃圾收集。你是被迫的 复制垃圾的行为 收集器并手动确定 对象是否应处于 记忆


,Ethan Nicholas

我对WeakReferences的一个实际应用是,如果你有一个非常大的对象,而这个对象很少使用。你不想在不需要的时候把它保存在内存中;但是,如果另一个线程需要相同的对象,那么内存中也不需要两个对象。您可以在某处保留对对象的弱引用,并在使用该对象的方法中保留硬引用;当这两个方法都完成时,对象将被收集。

您可以使用weakhashmap来实现无资源缓存,用于扩展对象创建

但请注意,不希望有可变对象。
我用它将查询结果(执行大约需要400毫秒)缓存到一个文本搜索引擎中,该引擎很少更新。

我用谷歌代码搜索了“new WeakHashMap()”

我从GNU类路径项目和

  • Apache xbean项目:
  • Apache Lucene项目:

  • 这篇博文演示了这两个类的用法:。用法如下:

    private static IdMutexProvider MUTEX_PROVIDER = new IdMutexProvider();
    
    public void performTask(String resourceId) {
        IdMutexProvider.Mutex mutext = MUTEX_PROVIDER.getMutex(resourceId);
        synchronized (mutext) {
            // look up the resource and do something with it
        }
    }
    
    IdMutextProvider提供基于id的对象以进行同步。这些要求是:

    • 必须返回对同一对象的引用,以便同时使用等效ID
    • 必须为不同的ID返回不同的对象
    • 无释放机制(对象不会返回到提供程序)
    • 不得泄漏(未使用的对象可以进行垃圾收集)
    这是通过使用以下类型的内部存储映射实现的:

    WeakHashMap<Mutex, WeakReference<Mutex>>
    
    WeakHashMap
    
    对象既是键又是值。当映射外部没有硬引用对象时,可以对其进行垃圾收集。映射中的值与硬引用一起存储,因此必须将该值包装在WeakReference中以防止内存泄漏。最后一点在。

    WeakReference
    SoftReference
    需要明确的一个区别是a和a之间的区别

    基本上,
    WeakReference
    将由被引用的对象在没有硬引用的情况下进行。另一方面,
    SoftReference
    d对象往往会被垃圾收集器留下,直到它真正需要回收内存


    保存在
    WeakReference
    s中的缓存将非常无用(在
    WeakHashMap
    中,是弱引用的键)
    SoftReferences
    在您想要实现一个可以随可用内存增长和收缩的缓存时,对值进行包装非常有用。

    如上所述,只要强引用存在,弱引用就会保持

    一个示例用法是在监听器中使用WeakReference,这样一旦对其目标对象的主引用消失,监听器就不再处于活动状态。 请注意,这并不意味着WeakReference将从侦听器列表中删除,仍然需要清理,但可以在预定时间执行清理。 这还可以防止所听对象包含强引用,最终成为内存膨胀的来源。 示例:Swing GUI组件引用的模型具有比窗口更长的生命周期


    在如上所述使用侦听器时,我们很快意识到从用户的角度“立即”收集对象。

    WeakReferences和
    WeakHashMap
    s的一个常见用法是为对象添加属性。有时,您希望向对象添加一些功能或数据,但子类化和/或组合不是一个选项。在这种情况下,显而易见的做法是创建一个hashmap,将要扩展的对象链接到要添加的属性。然后,无论何时你需要这个房产,你都可以在地图上查找它。但是,如果要添加特性的对象往往会被破坏和大量创建,则最终可能会导致地图中的许多旧对象占用大量内存

    如果您使用
    WeakHashMap
    ,则当程序的其余部分不再使用对象时,这些对象将立即离开您的贴图,这是所需的行为

    我不得不这样做来保护自己
    manager.registerListener(myListenerImpl);
    
    Set<ListenerType> listenerSet =
        Collections.newSetFromMap(new WeakHashMap<ListenerType, Boolean>());