Java 中有 SoftHashMap 吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/264582/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 12:12:41  来源:igfitidea点击:

Is there a SoftHashMap in Java?

javahashmapweak-referencessoft-references

提问by tigger

I know there is a WeakHashMapin java.util, but since it uses WeakReferences for everything, which is only referenced by this Map, referenced objects will get lost on the next GC cycle. So it's nearly useless if you want to cache random data, which is very likely to be requested again without being Hard-linked the rest of the time. The best solution would be a map, which uses SoftReferences instead, but I didn't find one in the Java RT Package.

我知道有一个WeakHashMapin java.util,但是因为它对WeakReference所有东西都使用s ,它只被 thisMap引用,被引用的对象将在下一个 GC 周期丢失。因此,如果您想缓存随机数据,这几乎是无用的,这很可能会再次被请求而其余时间都没有进行硬链接。最好的解决方案是一张地图,它使用SoftReferences 代替,但我没有在 Java RT Package 中找到。

采纳答案by VonC

Edit (Aug. 2012):

编辑(2012 年 8 月):

It turns out that currently the best solution are probably Guava 13.0's Cacheclasses, explained on Guava's Wiki- that's what I'm going to use. It even supports building a SoftHashMap(see CacheBuilder.newBuilder().softKeys()), but it is probably not what you want, as Java expert Jeremy Manson explains (below you'll find the link).

事实证明,目前最好的解决方案可能是 Guava 13.0 的Cache类,在Guava 的 Wiki上有解释——这就是我要使用的。它甚至支持构建SoftHashMap(参见CacheBuilder.newBuilder().softKeys()),但它可能不是您想要的,正如 Java 专家 Jeremy Manson 所解释的(您将在下面找到链接)。



Not that I know of(Nov. 2008), but you kind find some implementation of SoftHashMapon the net.

知道(2008 年 11 月),但是您可以SoftHashMap在网上找到一些实现。

Like this one: SoftHashMapor this one.

像这个:SoftHashMap或者这个



Edit (Nov. 2009)
As Matthiasmentions in the comments, the Google GuavaMapMakerdoes use SoftReferences:

编辑(2009 年 11 月)
正如Matthias在评论中提到的,Google Guava MapMaker确实使用了 SoftReferences:

A ConcurrentMapbuilder, providing any combination of these features:

  • soft or weak keys,
  • soft or weak values,
  • timed expiration, and
  • on-demand computation of values.

一个ConcurrentMap构建器,提供这些功能的任意组合:

  • 软键或弱键,
  • 软值或弱值,
  • 定时到期,和
  • 按需计算值。

As mentioned in this thread, another JSR166y candidate:

正如这个线程中提到的,另一个 JSR166y 候选者:

jsr166y.ConcurrentReferenceHashMap

jsr166y.ConcurrentReferenceHashMap

It provides an alternative concurrent reference map to the Google implementation (which relies on a background thread to evict entries)

它为 Google 实现提供了另一种并发参考映射(它依赖于后台线程来驱逐条目)



Edit (August 2012)

编辑(2012 年 8 月)

The Google implementation uses a background thread only when timed expiration of entries is requested. In particular, it simply uses java.util.Timer, which is not so intrusive as having a separate background thread.

Google 实现仅在请求条目的定时过期时使用后台线程。特别是,它只是使用java.util.Timer,这不像具有单独的后台线程那样具有侵入性。

Jeremy Manson recommends, for any cache, using this feature to avoid the dangers of SoftReference: http://jeremymanson.blogspot.de/2009/07/how-hotspot-decides-to-clear_07.html

Jeremy Manson 建议,对于任何缓存,使用此功能来避免 SoftReference 的危险:http: //jeremymanson.blogspot.de/2009/07/how-hotspot-decides-to-clear_07.html

There's another implementation from Apache Commons, namely org.apache.commons.collections.map.ReferenceMap; it does not support timed removal, but it does support choosing whether keys should be compared by identity or by equality. Moreover, this implementation is not concurrent - it can be made synchronized, but that works less well under accesses from multiple threads.

还有一个来自Apache Commons的实现,即org.apache.commons.collections.map.ReferenceMap;它不支持定时删除,但它支持选择键是否应该通过身份或相等进行比较。此外,这个实现不是并发的——它可以被同步,但是在来自多个线程的访问下效果不太好。

回答by jb.

There is an example implementation in 98 issue of java specialists newsletter

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

回答by luke

If you want to implement a cache softreferences are definetly a better idea than weak references, but it puts your entire cache removal policy in the hands of the garbage collector. which is probably not what you want.

如果你想实现一个缓存,软引用绝对是比弱引用更好的主意,但它把你的整个缓存删除策略放在垃圾收集器的手中。这可能不是你想要的。

If cache removal policy is important your are going to need to do it on your own most likely using regular references. However you are going to have to decide when to eject items and which to eject. If you only want to lose things when you are running out of heap space you can query available heap space via:

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

Runtime.getRuntime().getFreeMemory();

Then once free memory drops below a certain amount you can start either dropping items. Or you could just implement a max size for the cache and use that to decide when to drop things.

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

here's an LRU cachei designed with O(1) insertion, deletion and lookup time, that has a configurable max number of elements. If you want a cache this is going to be a better solution imho than a SoftHashMap.

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

The softreferences are a great way to create a growable cache. So the ideal solution would be to use a SoftHashMap along with a regular fixed size cache. have all inserts into the cache go into both the fixed cache and the soft hash map then to reference something just see if its in the soft hashmap (and update the reference time in the cache). this way all your most important items (according to your chosen policy LRU, MFU,...) will never be removed because they are hard referenced in the cache but you will also hold on to more things (with no policy control) as long as there is sufficient memory.

软引用是创建可增长缓存的好方法。因此,理想的解决方案是使用 SoftHashMap 和常规固定大小的缓存。让缓存中的所有插入都进入固定缓存和软散列映射,然后引用某些东西,看看它是否在软散列映射中(并更新缓存中的引用时间)。这样,您所有最重要的项目(根据您选择的策略 LRU、MFU 等)将永远不会被删除,因为它们在缓存中被硬引用,但您也将保留更多的东西(没有策略控制)只要因为有足够的内存。

回答by Gili

I am familiar with two libraries that offer a SoftHashMap implementation:

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

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

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

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

  2. 谷歌收藏:com.google.common.collect.ReferenceMap

回答by Joel

Have you considered using an LRUMapinstead of a soft HashMap? You get more control over what gets stored (or at least, how much).

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

回答by DallinDyer

Apache Shirocomes with a SoftHashMap designed for caching. Its based on the article posted by jb above and licensed under Apache v2. You can find the documentation hereand the source code here.

Apache Shiro带有专为缓存设计的 SoftHashMap。它基于上面 jb 发表的文章,并在 Apache v2 下获得许可。你可以找到的文件在这里和源代码在这里