【问题标题】:Android memory leaks understandingAndroid内存泄漏理解
【发布时间】:2013-05-30 12:48:57
【问题描述】:

我正在阅读名为"Effective Java" by Joshua Bloch 的书,其中有一段代码会导致内存泄漏。

public class Stack {
 private Object[] elements;
 private int size = 0;
 private static final int DEFAULT_INITIAL_CAPACITY = 16;

public Stack() {
    elements = new Object[DEFAULT_INITIAL_CAPACITY];
}

public void push(Object e) {
    ensureCapacity();
    elements[size++] = e;
}

public Object pop() {
    if (size == 0)
        throw new EmptyStackException();
    return elements[--size];
}

/**
 * Ensure space for at least one more element, roughly
 * doubling the capacity each time the array needs to grow.
 */
private void ensureCapacity() {
    if (elements.length == size)
        elements = Arrays.copyOf(elements, 2 * size + 1);
}

}

pop 方法应替换为

public Object pop() {
    if (size == 0)
        throw new EmptyStackException();
    Object result = elements[--size];
    elements[size] = null; // Eliminate obsolete reference
    return result;
} 

我很清楚。代码(见下文)会导致内存泄漏吗?例如,我多次旋转屏幕,private ArrayList<String> mArrayList = new ArrayList<String>(CAPASITY); 每次都分配内存。

public class MainActivity extends Activity implements OnClickListener {

    private static final int CAPASITY = 10000;
    private ArrayList<String> mArrayList = new ArrayList<String>(CAPASITY);

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // Some work on mArrayList
    }

    @Override
    public void onClick(View v) {
        // Some work on mArrayList
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // TODO: mArrayList = null to prevent memory leaks. Is it necessary to do it?
    }

}

【问题讨论】:

  • 以何种方式泄漏?
  • @blackbelt,我编辑了这个问题。例如,每次屏幕旋转后分配内存。
  • @RedPlanet,没有内存泄漏,mArrayList 将包含对新 ArrayList 的引用,并且没有对旧 ArrayList 的引用,因此将被垃圾回收。抱歉跑题了,你看第二版了吗?你在莫斯科哪里弄到的?花了多少钱?
  • @SpongeBobFan,我已经阅读了几个星期。有没有更好的版本?我不记得我在哪里买的。
  • @RedPlanet,第一版翻译成俄语,第二版没有。第二版更新了很多(2008 年对比 2001 年),但我只在 1 家网上商店看到它,价格为 200 美元,交货期为 21 天。

标签: android list memory-leaks android-activity


【解决方案1】:

// TODO: mArrayList = null 以防止内存泄漏。有必要这样做吗?

不可以,活动对象及其成员(例如mArrayList)可以进行垃圾回收。您的活动代码没有显示任何会使对象引用过长的内容。

【讨论】: