質問

弱参照の使用は、これまでに実装を見たことがないため、それらのユースケースが何であり、実装がどのように機能するかを理解しようとしています。 WeakHashMap または WeakReference を使用する必要があったのはいつですか?

役に立ちましたか?

解決

  

強参照の問題の1つは   特に非常に大きいキャッシュ   画像のような構造。あなたが   動作しなければならないアプリケーションがあります   次のようなユーザー提供の画像   私が取り組んでいるウェブサイトのデザインツール。   当然これらをキャッシュしたい   イメージ、ディスクからロードするため   非常に高価でありたい   2つの可能性を避ける   (潜在的に巨大な)のコピー   一度にメモリ内の画像。

     

画像キャッシュは   次の場合に画像をリロードしないようにします   絶対にする必要はありません、あなたは   キャッシュが   常にへの参照を含む   すでにメモリ内にある画像。と   ただし、通常の強い参照   その参照自体が強制的に   メモリに残るイメージ、   いつかを判断する必要があります   画像はもう必要ありません   メモリからキャッシュから削除し、   の対象となるように   ガベージコレクション。あなたは   ゴミの動作を複製する   収集し、手動で決定する   オブジェクトが含まれるべきかどうか   メモリ。

弱い参照について、イーサンニコラス

他のヒント

明確にするべき1つの違いは、 WeakReference SoftReference の違いです。

基本的に WeakReference は、参照されるオブジェクトに hard 参照がなくなると、JVMによって熱心にGC-dされます。一方、 SoftReference dオブジェクトは、実際にメモリを再利用する必要が生じるまで、ガベージコレクタによって残される傾向があります。

WeakReference 内に保持されているキャッシュは、ほとんど役に立たないでしょう( WeakHashMap では、弱いキーです参照)。 SoftReferences は、使用可能なメモリで拡大および縮小できるキャッシュを実装するときに値をラップするのに役立ちます

WeakReference sおよび WeakHashMap sの一般的な使用法の1つは、オブジェクトにプロパティを追加することです。オブジェクトにいくつかの機能やデータを追加したい場合がありますが、その場合はサブクラス化や構成はオプションではありません。次に、プロパティが必要なときはいつでもマップで検索できます。ただし、プロパティを追加するオブジェクトが破壊されて作成される傾向がある場合、マップ内の多くの古いオブジェクトが大量のメモリを消費することになります。

代わりに WeakHashMap を使用すると、オブジェクトはプログラムの残りの部分で使用されなくなるとすぐにマップを離れます。これは望ましい動作です。

1.4.2と1.5の間のJREの変更を回避するために java.awt.Component にデータを追加するためにこれを行う必要がありましたが、すべてのコンポーネントをサブクラス化することで修正できましたint( JButton JFrame JPanel ....)に興味がありましたが、これははるかに少ないコードではるかに簡単でした。

WeakHashMap および WeakReference のもう1つの便利なケースは、リスナーレジストリの実装です。

特定のイベントを聞きたいものを作成する場合、通常はリスナーを登録します。例:

manager.registerListener(myListenerImpl);

manager WeakReference を使用してリスナーを保存している場合、レジスタを削除する必要はありません。 manager.removeListener(myListenerImpl)を使用します。これは、リスナーまたはリスナーを保持するコンポーネントが使用できなくなると自動的に削除されるためです。

もちろん、手動でリスナーを削除することもできますが、 忘れたり忘れたりしても、メモリリークは発生せず、リスナーのガベージコレクションが妨げられることもありません。

WeakHashMap はどこにあるのですか?

登録済みリスナーを WeakReference sとして保存するリスナーレジストリには、これらの参照を保存するコレクションが必要です。標準のJavaライブラリには WeakHashSet の実装はありませんが、 WeakHashMap だけがありますが、後者を簡単に使用して「実装」できます。最初の機能:

Set<ListenerType> listenerSet =
    Collections.newSetFromMap(new WeakHashMap<ListenerType, Boolean>());

この listenerSet を使用して新しいリスナーを登録するだけで、セットに追加するだけで、明示的に削除されなくても、リスナーが参照されなくなった場合、自動的に削除されますJVMによって。

このブログ投稿では、両方のクラスの使用方法を示しています。 Java: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がリスナーリストから削除されることを意味するものではないことに注意してください。クリーンアップは引き続き必要ですが、たとえばスケジュールされた時間に実行できます。 これは、リッスンするオブジェクトが強い参照を保持することを防ぎ、最終的にはメモリの膨張の原因となるという効果もあります。 例:ウィンドウよりも長いライフサイクルを持つモデルを参照するSwing GUIコンポーネント。

上記のようにリスナーで遊んでいると、オブジェクトが「即座に」収集されることがすぐにわかりました。ユーザーの観点から。

WeakReferencesで実際に使用していたのは、めったに使用されない単一の非常に大きなオブジェクトがある場合です。不要な場合はメモリに保存したくないでしょう。しかし、別のスレッドが同じオブジェクトを必要とする場合、それらのうちの2つもメモリに入れたくありません。オブジェクトへの弱い参照をどこかに保持し、それを使用するメソッドにハード参照を保持できます。メソッドが両方とも終了すると、オブジェクトが収集されます。

&quot; new WeakHashMap()&quot;のGoogleコード検索を行いました。

GNUクラスパスプロジェクトから多数の一致を取得しました

  1. Apache xbeanプロジェクト: WeakHashMapEditor.java
  2. Apache Luceneプロジェクト: CachingWrapperFilter.java

weakhashmapを使用して、拡張オブジェクト作成用のリソースフリーキャッシュを実装できます。

しかし、可変オブジェクトを持つことは望ましくないことに注意してください。 クエリ結果(実行に約400ミリ秒かかります)をテキスト検索エンジンにキャッシュするために使用しました。これはめったに更新されません。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top