弱参照の使用は、実装を見たことがないので、それらの使用例と実装がどのように機能するかを理解しようとしています。WeakHashMap
またはを使用する必要があったのWeakReference
はいつですか。また、どのように使用されましたか?
10 に答える
強力な参照に関する問題の1つは、特に画像のような非常に大きな構造でのキャッシュです。私が取り組んでいるWebサイトのデザインツールのように、ユーザーが提供した画像を処理する必要のあるアプリケーションがあるとします。当然、これらのイメージをキャッシュする必要があります。これは、ディスクからイメージをロードするのに非常にコストがかかり、(巨大な可能性のある)イメージのコピーが一度に2つメモリに存在する可能性を回避するためです。
画像キャッシュは、絶対に必要のないときに画像を再読み込みできないようにするため、キャッシュには、すでにメモリ内にある画像への参照が常に含まれている必要があることがすぐにわかります。ただし、通常の強力な参照では、その参照自体が画像をメモリに残します。そのため、画像がメモリに不要になった時期を判断し、キャッシュから削除して、ガベージコレクションの対象にする必要があります。ガベージコレクターの動作を複製し、オブジェクトをメモリ内に配置する必要があるかどうかを手動で判断する必要があります。
弱参照を理解する、Ethan Nicholas
WeakReference
対SoftReference
明確にするべき 1 つの違いは、 aWeakReference
と aの違いSoftReference
です。
基本的に、参照されるオブジェクトがそれへのハードWeakReference
参照を持たなくなると、 JVMによって熱心にGCされます。一方、d オブジェクトは、実際にメモリを再利用する必要があるまで、ガベージ コレクターによって取り残される傾向があります。SoftReference
値WeakReference
がs内に保持されているキャッシュは、まったく役に立ちません ( では、WeakHashMap
弱く参照されるのはキーです)。SoftReferences
使用可能なメモリで拡大および縮小できるキャッシュを実装する場合に、値をラップするのに役立ちます。
WeakReference
特にs とs の一般的な用途の 1 つWeakHashMap
は、オブジェクトにプロパティを追加することです。オブジェクトに機能やデータを追加したい場合がありますが、サブクラス化や合成はオプションではありません。その場合、明らかにすべきことは、拡張したいオブジェクトを追加したいプロパティにリンクするハッシュマップを作成することです. 物件が必要なときはいつでも、マップで検索するだけです。ただし、プロパティを追加するオブジェクトが頻繁に破棄および作成される傾向がある場合、マップ内の多くの古いオブジェクトが大量のメモリを消費することになります。
代わりにa を使用するWeakHashMap
と、オブジェクトはプログラムの残りの部分で使用されなくなるとすぐにマップから離れます。これは望ましい動作です。
1.4.2 と 1.5 の間の JRE の変更を回避するために、いくつかのデータを追加するためにこれを行う必要がありました。関心のあるすべてのコンポーネントを int ( 、、....)java.awt.Component
にサブクラス化することで修正できましたが、これは大したことではありませんでした。はるかに少ないコードで簡単に。JButton
JFrame
JPanel
このブログ投稿では、両方のクラスの使用方法を示しています: Java: synchronizing on an ID . 使用法は次のようになります。
private static IdMutexProvider MUTEX_PROVIDER = new IdMutexProvider();
public void performTask(String resourceId) {
IdMutexProvider.Mutex mutext = MUTEX_PROVIDER.getMutex(resourceId);
synchronized (mutext) {
// look up the resource and do something with it
}
}
IdMutextProvider は、同期する ID ベースのオブジェクトを提供します。要件は次のとおりです。
- 同等の ID を同時に使用するには、同じオブジェクトへの参照を返す必要があります
- ID ごとに異なるオブジェクトを返さなければならない
- 解放メカニズムなし (オブジェクトはプロバイダーに返されません)
- リークしてはいけません (未使用のオブジェクトはガベージ コレクションの対象となります)
これは、次のタイプの内部ストレージ マップを使用して実現されます。
WeakHashMap<Mutex, WeakReference<Mutex>>
オブジェクトはキーと値の両方です。マップの外部にオブジェクトへのハード参照がない場合は、ガベージ コレクションを実行できます。マップ内の値はハード参照とともに格納されるため、メモリ リークを防ぐために値をWeakReferenceでラップする必要があります。この最後の点はjavadocで説明されています。
上記のように、強参照が存在する限り、弱参照が保持されます。
使用例は、リスナー内でWeakReferenceを使用することです。これにより、ターゲットオブジェクトへのメイン参照がなくなると、リスナーはアクティブでなくなります。これは、WeakReferenceがリスナーリストから削除されることを意味するものではないことに注意してください。クリーンアップは引き続き必要ですが、たとえば、スケジュールされた時間に実行できます。これは、リッスンされたオブジェクトが強力な参照を保持し、最終的にメモリの肥大化の原因となるのを防ぐ効果もあります。例:ウィンドウよりもライフサイクルが長いモデルを参照するSwingGUIコンポーネント。
上記のようにリスナーと遊んでいると、ユーザーの観点からオブジェクトが「すぐに」収集されることにすぐに気付きました。
たとえば、特定のクラスで作成されたすべてのオブジェクトを追跡したい場合。これらのオブジェクトを引き続きガベージ コレクションできるようにするには、オブジェクト自体ではなく、オブジェクトへの弱参照のリスト/マップを保持します。
誰かがファントム参照について説明してくれたら嬉しいです...
私がWeakReferencesに使用した実際の使用法の1つは、めったに使用されない単一の非常に大きなオブジェクトがある場合です。不要なときにメモリに保持したくありません。ただし、別のスレッドが同じオブジェクトを必要とする場合は、そのうちの2つをメモリに入れたくないでしょう。オブジェクトへの弱参照をどこかに保持し、それを使用するメソッドで強参照を保持できます。両方のメソッドが終了すると、オブジェクトが収集されます。
「newWeakHashMap()」をグーグルコード検索しました。
GNUクラスパスプロジェクトからたくさんの一致を取得し、
- Apache xbeanプロジェクト:WeakHashMapEditor.java
- Apache Luceneプロジェクト:CachingWrapperFilter.java
weakhashmap を使用して、リソースを使用しないキャッシングを実装して、拡張オブジェクトを作成できます。
ただし、変更可能なオブジェクトを持つことは望ましくないことに注意してください。これを使用して、めったに更新されないテキスト検索エンジンにクエリ結果 (実行に約 400 ミリ秒かかります) をキャッシュしました。