web-dev-qa-db-ja.com

JavaにSoftHashMapはありますか?

私はJava.utilWeakHashMapがあることを知っていますが、このWeakReferenceによってのみ参照されるすべてに対してMapsを使用するため、参照されるオブジェクトは次のGCサイクルで失われます。したがって、ランダムデータをキャッシュする場合はほとんど役に立ちません。これは、残りの時間にハードリンクされずに再度要求される可能性が非常に高いです。最善の解決策は、代わりにSoftReferencesを使用するマップですが、Java RT Package。

62
tigger

編集(2012年8月):

現在、最善の解決策は、おそらくGuava 13.0のCacheクラスであることがわかります。これは GuavaのWiki で説明されています-これが私が使用するものです。 SoftHashMapCacheBuilder.newBuilder().softKeys()を参照)のビルドもサポートしますが、JavaエキスパートのJeremy Mansonが説明しているように、これはおそらく望んでいることではありません。リンクを見つけます)。


そうではありません 知っています (2008年11月)。ただし、ネット上でSoftHashMapの実装を見つけていただければ幸いです。

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


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

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

  • ソフトキーまたは弱いキー、
  • ソフトまたは弱い値、
  • 時限満了、および
  • 値のオンデマンド計算。

this thread で述べたように、別の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で比較するか、同等で比較するかを選択できます。さらに、この実装は同時ではありません-同期させることはできますが、複数のスレッドからのアクセスではうまく機能しません。

28
VonC

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

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

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

20
Gili

98発行Java専門家ニュースレター に実装例があります

4
jb.

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

2
Joel

Apache Shiro には、キャッシング用に設計されたSoftHashMapが付属しています。それは上記のjbによって投稿され、Apache v2の下でライセンスされた記事に基づいています。ドキュメント here およびソースコード here を見つけることができます。

2
DallinDyer

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

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

Runtime.getRuntime().getFreeMemory();

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

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

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

1
luke