23

効果的なJavaは次のように述べています。

メモリ リークの 3 つ目の一般的な原因は、リスナーやその他のコールバックです。クライアントがコールバックを登録するが明示的に登録解除しない API を実装すると、何らかのアクションを起こさない限りコールバックが蓄積されます。コールバックが迅速にガベージ コレクションされるようにする最善の方法は、弱い参照のみを格納することです。たとえば、それらを WeakHashMap にキーとしてのみ格納します。

私はJavaの初心者です。コールバックで弱い参照を作成する方法と、それらがメモリ リークの問題を解決する方法を教えてもらえますか? ありがとう。

4

3 に答える 3

13

この記事を読む

重要なポイントは次のとおりです。

直接参照は、オブジェクトを作成またはアクセスするために追加のコーディングを必要としない強力な参照と考えることができます。残りの3種類の参照は、java.lang.refパッケージにあるReferenceクラスのサブクラスです。ソフト参照はSoftReferenceクラスによって提供され、弱参照はWeakReferenceクラスによって提供され、ファントム参照はPhantomReferenceによって提供されます。

ソフト参照はデータキャッシュのように機能します。システムメモリが少ない場合、ガベージコレクタは、参照がソフト参照のみであるオブジェクトを任意に解放できます。つまり、オブジェクトへの強い参照がない場合、そのオブジェクトはリリースの候補になります。ガベージコレクタは、OutOfMemoryExceptionをスローする前にソフト参照を解放する必要があります。

弱参照はソフト参照よりも弱いです。オブジェクトへの唯一の参照が弱参照である場合、ガベージコレクターはいつでもオブジェクトによって使用されるメモリを再利用できます。メモリ不足の状況は必要ありません。通常、オブジェクトによって使用されるメモリは、ガベージコレクタの次のパスで再利用されます。

ファントム参照は、クリーンアップタスクに関連しています。ガベージコレクターがファイナライズプロセスを実行してオブジェクトを解放する直前に通知を提供します。オブジェクト内でクリーンアップタスクを実行する方法と考えてください。

この応答が乱雑になるのを避けるために投稿しないWeakListModelリストが続きます。

于 2010-05-18T17:19:47.210 に答える
9

簡単な(大雑把な)例で概念を説明するには、次のことを考慮してください。

public interface ChangeHandler {
    public void handleChange();
}

public class FileMonitor {

    private File file;
    private Set<ChangeHandler> handlers = new HashSet<ChangeHandler>();

    public FileMonitor(File file) { 
        this.file = file;
    }

    public void registerChangeHandler(ChangeHandler handler) {
        this.handlers.add(handler);
    } 

    public void unregisterChangeHandler(ChangeHandler handler) {
        this.handlers.remove(handler);
    }

    ...
}

クライアント クラスがこのFileMonitorAPI を使用すると、次のようになります。

public class MyClass {

    File myFile = new File(...);
    FileMonitor monitor = new FileMonitor(myFile);

    public void something() {
        ...
        ChangeHandler myHandler = getChangeHandler();
        monitor.registerChangeHandler(myHandler);
        ...
    }
}

thenの作成者がハンドラの処理が完了したときにMyClass呼び出すのを忘れた場合、 は登録されたインスタンスを永遠に参照し、が破棄されるかアプリケーションが終了するまでメモリに残ります。unregisterChangeHandler()FileMonitorHashSetFileMonitor

これを防ぐために、Bloch は の代わりに弱参照コレクションを使用することを提案していHashSetます。これにより、 のインスタンスMyClassが破棄された場合、参照がモニターのコレクションから削除されます。

HashSetinFileMonitorを aに置き換えてWeakHashMap、ハンドラーをキーとして使用することもできます。後者は、オブジェクトへの他のすべての参照がなくなったときにコレクションからハンドラーを自動的に削除するためです。

于 2011-12-12T14:14:03.537 に答える
1

Androidでのメモリリーク — 特定、対処、回避

于 2016-07-22T11:43:43.520 に答える