什么是 WeakHashMap 以及何时使用它?

什么是 WeakHashMap? 什么时候应该使用它?WeakHashMapHashMap有什么不同?

104240 次浏览

如果对键对象没有其他强引用,那么弱散列映射中的元素可以由垃圾收集器回收,这使得它们对于缓存/查找存储非常有用。

弱引用不限于这些哈希表,您可以对单个对象使用 WeakReference。它们有助于节省资源,您可以保留对某些内容的引用,但允许在没有其他内容引用它时收集该内容。(顺便说一句,强引用就是普通的 java 引用)。还有一些弱引用,它们往往不像软引用那样容易收集(在最后一个强引用消失之后,它们往往不会挂起很长时间)

来自 JGuru:

WeakHashMap 是一种特殊的 Map 实现,其中 地图存储在 java.lang.ref.WeakReference 将密钥存储在弱引用中, 键-值对可以动态地是 从地图上消失的时候 参考的关键是来自弱者 这使得 WeakHashMap 一个优秀的实现 弱引用列表,其中条目 在其他地方没有使用的 没有任何副作用, 只是因为钥匙掉了, 并不意味着马上就会 如果系统有足够的 资源,弱关键参考 没有外部引用的 很长一段时间。

更多关于 参考文献的资料:

您可以使用 WeakHashmap 来减少因缓存某个对象而导致内存泄漏的可能性。每当删除对键的所有引用时,WeakHashMap 将自动删除条目。

正如其他人已经指出的,弱引用提供了一种方法,可以将对象用作键,而无需创建对它的强引用。如果您不希望损害 JVM 对对象进行垃圾收集的能力,但是仍然希望能够跟踪对象的某些方面,那么这种方法非常有用,这使得弱引用成为缓存或存储关于对象的元数据的理想方法。

我建议阅读有关 Java 中 强引用和弱引用“理解薄弱的参考文献”(Oracle 博客文章)。如果不了解其中的区别,数据结构本身就没有什么意义。

人们用它来实现“缓存内存”。 如果您有一些可重用的对象 通常在你的申请表中,以及他们的 建设是昂贵的,而且在那里 人太多了,不可能全部留下 在记忆中 你使用 WeakHashMap。

把当前不存在的对象放在那里 当需要这个物体时,把它拿出来 在大多数时间里 物体会留在地图上。 关键是它们没有被抓住 直接,但通过弱引用。 所以当我们跑步的时候,如果它变得非常“拥挤” 由于内存不足,gc 将被允许收集 他们。 所以每次你想把物体从 WeakHashMap,您必须确保它 还在那里,否则你需要 重现它。

有效 Java,第2版,第26页。

内存泄漏的另一个常见来源是缓存 对象引用到缓存中时,很容易忘记它的存在,并将它保留在 这个问题有几种解决方案。 如果您足够幸运,可以实现一个条目与之完全相关的缓存 只要在缓存之外有对其键的引用,就表示缓存 作为一个 弱 HashMap; 条目将被自动删除后,他们成为过时的。 请记住,弱 HashMap只有在所需的缓存生存期内才有用 项是由对键的外部引用而不是值确定的。

弱引用是关于 平易近人的,它让 垃圾收集器(GC)为您完成工作。 我认为,最好是理解弱参照系试图解决的问题,并看到它的实际行动:

  • IBM 文章关于:

    Java 理论与实践: 用弱引用堵塞内存泄漏。 使用全局映射的内存泄漏,识别内存泄漏,对救援的弱引用,..。

  • 关于何时使用 WeakHashMap 的 博客文章(链接过期):

    ... 如果 WeakHashMap 不适合缓存,那么它适合做什么? 实现规范映射是很好的 一些额外的信息到一个对象,你有一个强引用 在 WeakHashMap 中放入一个条目,该对象作为键,并且 额外的信息作为映射值。然后,只要你保持一个 强引用的对象,您将能够检查映射到 检索额外的信息。一旦释放对象, 映射条目将被清除,而额外信息所使用的内存 将被释放。

  • Java 关于 java.lang.ref 的文档

Weakhashmap 允许对其条目进行垃圾收集,而不是等待完整的散列表被使用。因此,当它的键不再正常使用时,它将自动删除单个值。

它可以用来防止内存泄漏,其中散列表从未回收,因为一个或多个键仍在使用,即使最大值不是,如用户数据等。.