我知道有一个 WeakHashMapjava.util, ,而是因为它使用 WeakReferences用于一切,这是唯一引用的这个 Map, ,引用对象将会获得失去了在下一GC循环。所以这是几乎无用的,如果你想缓随机数据,这是非常有可能再次请求没有被很难联剩下的时间。最好的解决办法是一张地图,其使用 SoftReferences相反,但我没有找到一个在Java RT包。

有帮助吗?

解决方案

编辑(。2012年):

事实证明,目前最好的解决方案是可能的番石榴13.0的 Cache 班,解释 番石榴是维基 -这是什么我的使用。它甚至支持建立一个 SoftHashMap (见 CacheBuilder.newBuilder().softKeys()),但这可能不是你想要的,因为Java专家杰里米*曼森的说明(下面你会找到的链接)。


不, 我知道的 (Nov.2008年),但你找到了一些执行情况 SoftHashMap 在网。

像这样的: SoftHashMap这一个.


编辑(Nov.2009年)
作为 马蒂亚斯 提到的评论意见, 谷歌的番石榴 制图师 不用SoftReferences:

一个 ConcurrentMap 建设者,提供任何结合这些特点:

  • 软弱或钥匙,
  • 软弱或价值,
  • 计时到期,
  • 在需求计算的值。

如前所在 这个线程, 另一JSR166y候选人:

jsr166y.ConcurrentReferenceHashMap

它提供了一种替代并发参考地图的谷歌的执行情况(其依赖的背景线驱逐项)


编辑(2012年)

谷歌执行使用一种背景线只有当时到期的条目被请求。特别是,它只是使用 java.util.Timer, 也不是那么侵入为具有单独的背景线。

杰里米*曼森的建议,对于任何缓,使用该功能,以避免的危险SoftReference:http://jeremymanson.blogspot.de/2009/07/how-hotspot-decides-to-clear_07.html

还有另外一个执行情况 Apache Commons, 即 org.apache.共用。集合。地图。ReferenceMap;它不支持定时拆除,但它不支持选择是否钥匙应该比通过身份或通过平等。此外,这种实现是不是并行-这可制同步的,但工作小以及在访问多线程。

其他提示

我熟悉两个提供SoftHashMap实现的库:

  1. Apache Commons :org.apache.commons.collections.map.ReferenceMap

  2. Google Collections :com.google.common.collect.ReferenceMap

98期java专家时事通讯中有一个示例实现

Apache Shiro 附带了一个专为缓存设计的SoftHashMap。它基于上面jb发布的文章,并在Apache v2下获得许可。您可以在此处找到文档,源代码此处

您是否考虑过使用 LRUMap 而不是软HashMap?您可以更好地控制存储的内容(或至少是多少)。

如果你想实现缓存,那么软引用肯定比弱引用更好,但它会将整个缓存删除策略放在垃圾收集器的手中。这可能不是你想要的。

如果缓存删除策略很重要,您将需要使用常规引用自行完成。但是,您将不得不决定何时弹出项目以及要弹出的项目。如果您只想在堆空间不足时丢失内容,则可以通过以下方式查询可用堆空间:

Runtime.getRuntime().getFreeMemory();

然后,一旦空闲内存低于一定数量,您就可以开始丢弃项目。或者您可以只为缓存实现最大大小,并使用它来决定何时放弃。

这是一个 LRU缓存我设计了O(1)插入,删除和查找时间,具有可配置的最大元素数。如果你想要一个缓存,这将是一个比SoftHashMap更好的解决方案。

软引用是创建可扩展缓存的好方法。所以理想的解决方案是使用SoftHashMap和常规固定大小的缓存。让所有插入到缓存中的插入都进入固定缓存和软哈希映射,然后引用一些东西,看看它是否在软散列图中(并更新缓存中的参考时间)。通过这种方式,所有最重要的项目(根据您选择的策略LRU,MFU,...)将永远不会被删除,因为它们在缓存中被硬引用,但您也将保留更多内容(没有策略控制)因为有足够的记忆。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top