【问题标题】:Android ArrayList and growing Object[] instances in heapAndroid ArrayList 和堆中不断增长的 Object[] 实例
【发布时间】:2013-07-21 17:41:33
【问题描述】:

我的应用中有“以下代码”:

...
new Thread(new Runnable(){
    @Override
    public void run(){
        while(true){
            ...
            firstArrayList.add(new CustomObject());
            ...
            secondArrayList.add(new Integer(integer1));
            secondArrayList.add(new Integer(integer2));
            ...
            if(roundOverCondition){
                firstArrayList.clear();
                secondArrayList.clear();
                Thread.sleep(3000);
            }
        }
    }
}).start();
...

我在 Eclipse 中做了四个堆转储。

  1. 线程启动前
  2. 线程运行一段时间后; roundOverCondition 从来都不是真的,然而
  3. roundOverCondition 第一次为真之后(firstArrayList 的大小为 230)
  4. roundOverCondition 第二次为真后(firstArrayList 的大小为 200)

结果如下:

  • 堆转储 2 显示堆中存在 Integer、CustomObject 和 java.lang.Object[] 的实例

  • 堆转储 3 显示不再存在 Integer 和 CustomObject 的实例堆。 java.lang.Object[] 的所有实例仍然存在

  • 堆转储 4 表明堆中存在更多 java.lang.Object[] 实例(没有 Integer 和 CustomObject 实例)

Integer 和 CustomObject 的实例数量的发展/行为符合预期。但是这个 java.lang.Object[] 实例是什么?为什么不收集垃圾?

谢谢和问候:)

【问题讨论】:

    标签: android arraylist memory-leaks heap-memory


    【解决方案1】:

    ArrayLists 由数组支持。您在堆转储中看到的Object[] 实例很可能是由ArrayList 创建的,这是将项目添加到列表的副作用。

    请咨询docs for ArrayList 并尝试使用大小构造函数(或 ensureCapacity())来检验假设。

    【讨论】:

    • 是的,你完全正确。在 ArrayList elementData = Arrays.copyOf(elementData, newCapacity);如果大小变得比容量大,则调用它。但是我还有一些不清楚的地方:
    • 即使每次我添加一个新对象时 ArrayList 都必须“调整”其内部数据数组(elementData)的大小,每个 ArrayList 的堆中应该只存在一个 Object[] 实例,对吧? ArrayList 是否泄漏!?
    • 这是ArrayList的一个实现细节;您通常不能假定类的内部具有超出其公共接口指定的特定行为。像 ArrayList 这样频繁使用的类不太可能发生泄漏。如果您想确定,请检查未完成的引用对象(在您的堆转储中)以及来源。
    猜你喜欢
    • 2013-01-09
    • 2011-11-07
    • 2016-02-24
    • 1970-01-01
    • 2015-04-25
    • 1970-01-01
    • 2011-09-17
    • 1970-01-01
    • 2013-02-11
    相关资源
    最近更新 更多