是否有一个SoftHashMap在Java?
-
06-07-2019 - |
题
我知道有一个 WeakHashMap
在 java.util
, ,而是因为它使用 WeakReference
s用于一切,这是唯一引用的这个 Map
, ,引用对象将会获得失去了在下一GC循环。所以这是几乎无用的,如果你想缓随机数据,这是非常有可能再次请求没有被很难联剩下的时间。最好的解决办法是一张地图,其使用 SoftReference
s相反,但我没有找到一个在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实现的库:
-
Apache Commons :org.apache.commons.collections.map.ReferenceMap
-
Google Collections :com.google.common.collect.ReferenceMap
醇>
98期java专家时事通讯中有一个示例实现
您是否考虑过使用 LRUMap 而不是软HashMap?您可以更好地控制存储的内容(或至少是多少)。
如果你想实现缓存,那么软引用肯定比弱引用更好,但它会将整个缓存删除策略放在垃圾收集器的手中。这可能不是你想要的。
如果缓存删除策略很重要,您将需要使用常规引用自行完成。但是,您将不得不决定何时弹出项目以及要弹出的项目。如果您只想在堆空间不足时丢失内容,则可以通过以下方式查询可用堆空间:
Runtime.getRuntime().getFreeMemory();
然后,一旦空闲内存低于一定数量,您就可以开始丢弃项目。或者您可以只为缓存实现最大大小,并使用它来决定何时放弃。
这是一个 LRU缓存我设计了O(1)插入,删除和查找时间,具有可配置的最大元素数。如果你想要一个缓存,这将是一个比SoftHashMap更好的解决方案。
软引用是创建可扩展缓存的好方法。所以理想的解决方案是使用SoftHashMap和常规固定大小的缓存。让所有插入到缓存中的插入都进入固定缓存和软哈希映射,然后引用一些东西,看看它是否在软散列图中(并更新缓存中的参考时间)。通过这种方式,所有最重要的项目(根据您选择的策略LRU,MFU,...)将永远不会被删除,因为它们在缓存中被硬引用,但您也将保留更多内容(没有策略控制)因为有足够的记忆。