65

WeakHashMapinがあることは知っていますが、これによってのみ参照されるすべてにsがjava.util使用されるため、参照されるオブジェクトは次のGCサイクルで失われます。したがって、ランダムなデータをキャッシュしたい場合はほとんど役に立ちません。ランダムなデータは、残りの時間はハードリンクされていなくても、再度要求される可能性が非常に高くなります。最善の解決策は、代わりにsを使用するマップですが、JavaRTパッケージで見つかりませんでした。WeakReferenceMapSoftReference

4

7 に答える 7

31

編集(2012年8月):

現在のところ、最良の解決策はおそらくGuava 13.0のCacheクラスであり、GuavaのWikiで説明されています。これを使用します。の構築もサポートしていますがSoftHashMap(を参照CacheBuilder.newBuilder().softKeys())、Javaの専門家であるJeremy Mansonが説明しているように(以下にリンクがあります)、おそらくあなたが望むものではありません。


私が知っていることではありませんが( 2008年11月)、SoftHashMapネット上でいくつかの実装を見つけてください。

これのように:SoftHashMapまたはこれ


編集(2009年11月)Matthiasがコメントで言及しているように、
GoogleGuavaMapMakerSoftReferencesを使用します

これらの機能の任意の組み合わせを提供するConcurrentMapビルダー:

  • ソフトキーまたはウィークキー、
  • ソフトまたはウィーク値、
  • 期限付きの有効期限、および
  • 値のオンデマンド計算。

このスレッドで述べたように、別のJSR166y候補:

jsr166y.ConcurrentReferenceHashMap

これは、Google実装への代替の同時参照マップを提供します(エントリを削除するためにバックグラウンドスレッドに依存します)


編集(2012年8月)

Googleの実装では、エントリの期限付きの有効期限が要求された場合にのみバックグラウンドスレッドを使用します。特に、それは単にを使用しますjava.util.Timer。これは、別個のバックグラウンドスレッドを持つほど邪魔になりません。

Jeremy Mansonは、どのキャッシュでも、SoftReferenceの危険を回避するために、この機能を使用することをお勧めします:http: //jeremymanson.blogspot.de/2009/07/how-hotspot-decides-to-clear_07.html

Apache Commonsからの別の実装、つまりorg.apache.commons.collections.map.ReferenceMapがあります。時限削除はサポートしていませんが、キーをIDと同等のどちらで比較するかを選択することはサポートしています。さらに、この実装は並行ではありません。同期させることはできますが、複数のスレッドからのアクセスではうまく機能しません。

于 2008-11-05T08:11:23.163 に答える
21

私は、SoftHashMap 実装を提供する 2 つのライブラリに精通しています。

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

  2. Google コレクション: com.google.common.collect.ReferenceMap

于 2008-12-30T03:56:02.053 に答える
4

Javaスペシャリストニュースレターの98号に実装例があります

于 2008-11-05T08:45:21.537 に答える
2

ソフト HashMap の代わりにLRUMapを使用することを検討しましたか? 何を保存するか (少なくとも、どれだけ保存するか) をより詳細に制御できます。

于 2009-11-26T16:37:02.407 に答える
2

Apache Shiroには、キャッシング用に設計された SoftHashMap が付属しています。上記の jb が投稿した記事に基づいており、Apache v2 でライセンスされています。ドキュメンテーションはここに、ソースコードはここにあります。

于 2011-10-05T15:27:15.090 に答える
1

キャッシュを実装したい場合、ソフト参照は弱い参照よりも明らかに優れたアイデアですが、キャッシュ削除ポリシー全体がガベージコレクターの手に委ねられます。これはおそらくあなたが望むものではありません。

キャッシュ削除ポリシーが重要な場合は、通常の参照を使用して自分で行う必要があります。ただし、アイテムをいつ排出するか、どのアイテムを排出するかを決定する必要があります。ヒープスペースが不足しているときにのみ物を失いたい場合は、次の方法で利用可能なヒープスペースを照会できます。

Runtime.getRuntime().getFreeMemory();

次に、空きメモリが特定の量を下回ったら、アイテムのドロップを開始できます。または、キャッシュの最大サイズを実装し、それを使用していつドロップするかを決定することもできます。

これは、構成可能な最大要素数を持つ、O(1) の挿入、削除、およびルックアップ時間で設計されたLRU キャッシュです。キャッシュが必要な場合、これは SoftHashMap よりも優れたソリューションになるでしょう。

ソフト参照は、拡張可能なキャッシュを作成する優れた方法です。したがって、理想的な解決策は、通常の固定サイズのキャッシュとともに SoftHashMap を使用することです。キャッシュへのすべての挿入を固定キャッシュとソフトハッシュマップの両方に移動させてから、何かを参照して、それがソフトハッシュマップにあるかどうかを確認します(そしてキャッシュの参照時間を更新します)。このようにして、すべての最も重要なアイテム (選択したポリシー LRU、MFU などによる) はキャッシュでハード参照されるため削除されることはありませんが、より多くのもの (ポリシー制御なし) を保持することもできます。十分なメモリがあるためです。

于 2008-11-05T15:54:24.023 に答える