0

Android でのメモリ リークについては既に質問しましたが、メモリ リークについてはまだよくわかりません。ここで、 によって受信されたデータを保持する必要がありますPhoneStateListener。インスタンスが 1 つだけ存在することを保証する必要があるため、Singleton パターンが役立ちます。

public class PhoneStateInfo {

    /** -1 until the first reception */
    private int mCid = -1;
    /** -1 until the first reception */
    private int mLac = -1;
    /** 0 until the first reception */
    private int mMcc;
    /** 0 until the first reception */
    private int mMnc;
    // And so on...

    private static PhoneStateInfo INSTANCE = new PhoneStateInfo();

    public static PhoneStateInfo getInstance() {
        return INSTANCE;
    }

    private PhoneStateInfo() {}

    /**
     * Reverts the single instance to its initial state
     * But if I have 10 or 20 fields which have various default values, it will be easy to forget something
     */
    void clear() {
        mCid = -1;
        mLac = -1;
        mMcc = 0;
        mMnc = 0;
        mRssi = -1;
        mSimState = TelephonyManager.SIM_STATE_UNKNOWN;
        mDeviceId = null;
        mSubscriberId = null;
        mPhoneNumber = null;
    }

    /**
     * Reverts the single instance to its initial state
     * Short and clear
     */
    static void clearInstance() {
        INSTANCE = null; // If I delete this line, memory leaks will occur
        // because the old reference is left alive will not be garbage-collected
        INSTANCE = new PhoneStateInfo();
    }
}

clear()およびclearInstance()メソッドを参照してください。私のコメントは正しいですか?

4

3 に答える 3

3
 INSTANCE = null; // If I delete this line, memory leaks will occur
 // because the old reference is left alive will not be garbage-collected
 INSTANCE = new PhoneStateInfo();

そうではありません。

新しい値を割り当てる前に、フィールドを null に設定する必要はありません。新しい値で上書きすることができます。

新しい値がない場合は、null に設定することをお勧めします (不要になったインスタンスを削除し、ガベージ コレクターに取得させるため)。

しかし、そうしなかったとしても、それを「メモリ リーク」とは呼びません。インスタンスが 1 つしかないため、非常に限定されているからです。未使用の場合でも、通常は「リーク」で発生するメモリ消費量が時間の経過とともに徐々に大きくなることはありません。

于 2013-06-04T16:46:19.970 に答える
1
static void clearInstance() {
    INSTANCE = null; // If I delete this line, memory leaks will occur
    // because the old reference is left alive will not be garbage-collected
    INSTANCE = new PhoneStateInfo();
}

そのコメントは正しくありません。最初の行は基本的に何もしません。古い PhoneStateInfo をポイントしないように INSTANCE を変更していますが、新しい PhoneStateInfo を割り当てると、古いものをポイントしないようにするという同じタスクも実行されます。

古い PhoneStateInfo がガベージ コレクションされるかどうかは、ここではわかりません。どこかのコードの別の部分がそれへの参照を作成した場合、その参照もなくなるまでコレクションの対象にはなりません。

于 2013-06-04T16:43:43.910 に答える
1

プレーンなJavaプログラムの場合、コメントは正しくありません。

nullオブジェクトが GC で使用可能であることを示すように設定する必要はありません。

ただし、プログラムでカスタムClassLoaders,を使用している場合はWeakReferenceThreadLocalsリークする可能性があります。

于 2013-06-04T16:45:52.667 に答える