WeakHashMap
inがあることは知っていますが、これによってのみ参照されるすべてにsがjava.util
使用されるため、参照されるオブジェクトは次のGCサイクルで失われます。したがって、ランダムなデータをキャッシュしたい場合はほとんど役に立ちません。ランダムなデータは、残りの時間はハードリンクされていなくても、再度要求される可能性が非常に高くなります。最善の解決策は、代わりにsを使用するマップですが、JavaRTパッケージで見つかりませんでした。WeakReference
Map
SoftReference
7 に答える
編集(2012年8月):
現在のところ、最良の解決策はおそらくGuava 13.0のCache
クラスであり、GuavaのWikiで説明されています。これを使用します。の構築もサポートしていますがSoftHashMap
(を参照CacheBuilder.newBuilder().softKeys()
)、Javaの専門家であるJeremy Mansonが説明しているように(以下にリンクがあります)、おそらくあなたが望むものではありません。
私が知っていることではありませんが( 2008年11月)、SoftHashMap
ネット上でいくつかの実装を見つけてください。
これのように:SoftHashMap
またはこれ。
編集(2009年11月)Matthiasがコメントで言及しているように、
GoogleGuavaMapMakerはSoftReferencesを使用します。
これらの機能の任意の組み合わせを提供する
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と同等のどちらで比較するかを選択することはサポートしています。さらに、この実装は並行ではありません。同期させることはできますが、複数のスレッドからのアクセスではうまく機能しません。
私は、SoftHashMap 実装を提供する 2 つのライブラリに精通しています。
Apache Commons : org.apache.commons.collections.map.ReferenceMap
Google コレクション: com.google.common.collect.ReferenceMap
Javaスペシャリストニュースレターの98号に実装例があります
ソフト HashMap の代わりにLRUMapを使用することを検討しましたか? 何を保存するか (少なくとも、どれだけ保存するか) をより詳細に制御できます。
キャッシュを実装したい場合、ソフト参照は弱い参照よりも明らかに優れたアイデアですが、キャッシュ削除ポリシー全体がガベージコレクターの手に委ねられます。これはおそらくあなたが望むものではありません。
キャッシュ削除ポリシーが重要な場合は、通常の参照を使用して自分で行う必要があります。ただし、アイテムをいつ排出するか、どのアイテムを排出するかを決定する必要があります。ヒープスペースが不足しているときにのみ物を失いたい場合は、次の方法で利用可能なヒープスペースを照会できます。
Runtime.getRuntime().getFreeMemory();
次に、空きメモリが特定の量を下回ったら、アイテムのドロップを開始できます。または、キャッシュの最大サイズを実装し、それを使用していつドロップするかを決定することもできます。
これは、構成可能な最大要素数を持つ、O(1) の挿入、削除、およびルックアップ時間で設計されたLRU キャッシュです。キャッシュが必要な場合、これは SoftHashMap よりも優れたソリューションになるでしょう。
ソフト参照は、拡張可能なキャッシュを作成する優れた方法です。したがって、理想的な解決策は、通常の固定サイズのキャッシュとともに SoftHashMap を使用することです。キャッシュへのすべての挿入を固定キャッシュとソフトハッシュマップの両方に移動させてから、何かを参照して、それがソフトハッシュマップにあるかどうかを確認します(そしてキャッシュの参照時間を更新します)。このようにして、すべての最も重要なアイテム (選択したポリシー LRU、MFU などによる) はキャッシュでハード参照されるため削除されることはありませんが、より多くのもの (ポリシー制御なし) を保持することもできます。十分なメモリがあるためです。