0

我已经询问过Android 上的内存泄漏,但我还不太了解内存泄漏。现在我必须保存一些接收到的数据PhoneStateListener。单例模式很方便,因为我应该保证只有一个实例存在。

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(以摆脱不再需要的实例并让垃圾收集器处理它)。

但即使你没有,我也不会称它为“内存泄漏”,因为它是非常有限的,因为只有一个实例。即使未使用,内存消耗也不会随着时间的推移逐渐变大,这通常是“泄漏”。

于 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();
}

那条评论是不正确的。第一行基本上什么都不做。您正在更改 INSTANCE 以不再指向旧的 PhoneStateInfo,但分配新的 PhoneStateInfo 也完成了使其不再指向旧的相同的任务!

您不能从这里真正确定旧的 PhoneStateInfo 是否会被垃圾收集。如果某处的另一段代码创建了对它的引用,则在该引用也消失之前,它没有资格被收集。

于 2013-06-04T16:43:43.910 回答
1

对于普通的 java 程序,您的评论不正确。

不需要设置null对象来标记它对 GC 可用。

但是,如果您的程序使用 custom ClassLoaders, WeakReferenceThreadLocals它可能会泄漏。

于 2013-06-04T16:45:52.667 回答