4

私はLRU cacheJavaで実装しようとしています。これは次のことができるはず
です。サイズを動的に変更する。SoftReferenceにサブスクライブするように計画しているという意味でReferenceQueue。したがって、メモリ消費量に応じて、キャッシュサイズは異なります。

値がソフト参照になる場所を使用ConcurrentHashMapし、定期的にキューをクリアしてマップを更新する予定です。
しかし、上記の問題は、どうすればそれを作成できるLRUかということです。

GCを制御できないことは知っていますが、キャッシュ内のすべての可能なオブジェクトが使用状況に応じて(つまり、前回)ソフトに到達可能になるように(キャッシュ内の)値への参照を管理できますか?アクセスされました)、ランダムな方法ではありません。

4

3 に答える 3

4

弱参照もソフト参照も、これにはあまり適していません。WeakReferences は、オブジェクトに強力な参照がなくなるとすぐにクリアされる傾向があり、ソフト参照は、ヒープが最大サイズに成長した後、またはそれ以外の場合に OutOufMemoryError をスローする必要がある場合にのみクリアされます。

通常、参照サブクラスよりもVMにとってはるかに安価な定期的な強力な参照を使用した時間ベースのアプローチを使用する方が効率的です(プログラムとGCの処理が速く、参照自体に余分なメモリを使用しません)。つまり、一定時間使用されていないすべてのオブジェクトを解放します。これは、参照キューを操作するためにとにかく必要な定期的な TimerTask で確認できます。つまり、オブジェクトの作成に 10 ミリ秒かかり、最後に使用してから 1 秒以内に保持すると、すべてのオブジェクトを永久に保持する場合よりも平均で 1% 遅くなるだけです。ただし、使用するメモリが少ない可能性が高いため、実際には高速になります。

編集:これを実装する 1 つの方法は、内部で 3 つのバケットを使用することです。キャッシュに配置されるオブジェクトは、常にバケット 0 に挿入されます。オブジェクトが要求されると、キャッシュは 3 つのバケットすべてを順番に検索し、まだ存在しない場合はバケット 0 に配置します。TimerTask は一定の間隔で呼び出され、バケット 2 をドロップし、バケット リストの先頭に新しい空のバケットを配置するだけで、新しいバケット 0 が空になり、以前のバケット 0 が 1 になり、以前のバケット 1 がバケットになります。 2. これにより、アイドル状態のオブジェクトが少なくとも 1 回、多くても 2 回のタイマー間隔で存続し、間隔ごとに複数回アクセスされるオブジェクトの取得が非常に高速になることが保証されます。このようなデータ構造の総メンテナンス オーバーヘッドは、参照オブジェクトと参照キューに基づくすべてのものよりもかなり小さくなります。

于 2012-08-03T13:19:43.467 に答える
1

これらのキャッシュのいくつかを同時に必要としない限り、あなたの質問は本当に意味がありません。キャッシュが 1 つしかない場合は、サイズ制限を設けず、常に を使用してWeakReferenceください。こうすることで、キャッシュは利用可能なすべての空きメモリを自動的に使用します。

ただし、システム管理者との熱い議論の準備をしておいてください。システム管理者は、アプリにメモリ リークがあり、「すぐにクラッシュするでしょう!」と不平を言うでしょう。はぁ

もう 1 つのオプションは、EHCache のような成熟したキャッシュ ライブラリを使用することです。なぜなら、 EHCacheはキャッシュについて知っておくべきすべてのことを既に知っており、文字通り何年も費やしてそれらを正しくするためです。コードのデバッグに何年も費やして、Java メモリ モデルのすべてのコーナー ケースで動作するようにしたい場合を除き、今回は車輪の再発明を避けることをお勧めします。

于 2012-08-03T12:58:18.180 に答える
0

LinkedHashMapはアクセス順序をサポートし、LRUマップとして使用するため、使用します。最大サイズは可変です。

使用法に基づいて弱い参照とソフト参照を切り替えるのは、正しく行うのが非常に難しいためです。a)キャッシュが排他的に使用している量、b)システムによって使用されている量、c)フルGC後に使用される量を判断するのは困難です。

弱い参照とソフト参照はGCでのみクリーンアップされ、それらを破棄または変更しても、GCが実行されるまでメモリが解放されないことに注意してください。

于 2012-08-03T12:38:03.057 に答える