2011-12-12 12 views
17

私は尋ねました、この質問読んでいた:Avoid memory leaks in callbacks?匿名のリスナーは弱い参照と互換性がありませんか?

そして、誰かが次のように答えまで私は、かなり混乱していた:

「このアプローチの問題は、あなただけ参照されているリスナーを持つことができないですがそれは(次のGCに)ランダムに消えますようコレクション」

は私が私の理解で正しいアムでのWeakHashMapに保存されているときのように、弱い参照を使用していること、匿名のリスナーと互換性がありませんか?

public static void main(String[] args) { 
    final Observable obs = new SomeObservable(); 
    obs.addObserver(new Observer() { 
     public void update(final Observable o, final Object arg) { 
      System.out.println("Notified"); 
     } 
    }); 
    obs.notifyObservers(); 
    ... // program continues its life here 
} 

private static final class SomeObservable extends Observable { 

    @Override 
    public void addObserver(final Observer o) { 
     super.addObserver(o); 
     setChanged(); // shouldn't be done from here (unrelated to the question) 
    } 

} 

そして私はCopyOnWriteArrayListと(明らかに上記観察可能が古いベクトルが、その一例に過ぎを使用して、デフォルトを使用してリスナーを追跡:

は、私は通常、次のようにリスナーを渡しますリスナーとして使用するための匿名クラスの作成方法を示します)。

ボーナスの質問:観察可能な主体がWeakHashMapを使用する場合、匿名リスナーへの参照はいつGCの対象となりますか? メインメソッドが終了したら? obs.addObserverコールが終了したらすぐに?

匿名クラスのインスタンスへの参照がGCのために保持され/保存され/表示される場所について/私はちょっと混乱します。

正常な参照を保持している場合は、GCには適格ではありませんが、WeakHashMapのときはいつですか GCのリスナーは正確ですか?

答えて

3

オブジェクトがWeakHashMapのキーにすぎない場合、そのオブジェクトは適格であり、次のGCでクリーンアップされる可能性があります。

Weak参照コレクションを使用するという考えは、もはや参照されていないリスナーを暗黙的に削除することです。 (これにより、メモリリークの可能性が回避されます)問題は、リスナーを時期尚早に「ランダム」な時点で削除できることです。

+1

ご協力いただきありがとうございます。しかし、私の質問は、特に匿名のリスナーに特に関係します。WeakHashMapに匿名リスナーへの参照を置くと、その匿名リスナーが別の場所に保管されているという別の参照がありますか?そうでない場合は、GCの瞬間はどのようになりますか?その後、電話しますか? –

6

はい、あなたは正しいです(WeakHashMapと同様に)ウィークリファレンスを持つリスナーを維持するリスニング可能なクラスは、独自の永続性を必要とします。リスナーが子と親を持つリスナー階層に使用できます。

WeakReference以外の用途では、明示的なremoveListenerを呼び出す必要があります。リスナーオブジェクトがリッスン可能なオブジェクトの長さを超えない限り、ほとんどのユースケースでは問題ありませんが、匿名クラスでは問題ありません。クラス体外最終オブジェクトにアクセスするとき

匿名クラスのインスタンスと

リーク(GC防止)がのみ起こり得ます。

注:WeakHashMap i.a. Map.Entryのそれ自身のサブクラスに対して弱参照を使用します。これは時にはかなり気になるかもしれません。

関連する問題