【问题标题】:Does an ArrayList have to be set to null before assigning it another new array?在分配另一个新数组之前,必须将 ArrayList 设置为 null 吗?
【发布时间】:2014-09-01 05:21:41
【问题描述】:

我有一个名为 mHomeworks 的数组。对于 onResume,我调用:

public void onResume() {
    super.onResume();
    ((HomeworkAdapter)getListAdapter()).notifyDataSetChanged();
    mHomeworks = HomeworkLab.get(getActivity()).getHomework();//update list
}

关于内存管理,我应该调用:

    mHomeworks.removeAll(mHomeworks);
    mHomeworks = null;

【问题讨论】:

  • 如果您必须从Collection 中删除所有元素,请使用clear() 方法。比removeAll()效率更高。

标签: java android arrays memory memory-management


【解决方案1】:

任何没有对它的引用的对象都有资格进行垃圾回收,而您无需对其执行任何操作。所以,通常情况下,mHomeworks = HomeworkLab.get(getActivity()).getHomework(); 很好,因为它会清除对旧对象的引用并允许回收内存(假设它没有在其他任何地方引用)。

如果 mHomeworks 在新分配之前和之后用尽了您的大量可用内存,则例外情况。在新分配发生之前,旧内存将无法被垃圾收集,因此两个对象需要同时在内存中短暂停留。如果您没有足够的内存,这可能会导致速度变慢或引发 OutOfMemory 异常。在这种情况下,mHomeworks = null; 足以释放内存。当然,您可能需要有非常大的列表才能做到这一点。

您绝对不想做的是mHomeworks.removeAll(mHomeworks);,因为这会导致同时修改列表。在内部,它会在迭代列表时从列表中删除某些内容,从而破坏迭代器并引发异常。

【讨论】:

  • 很好的答案。我想补充一点,这个例外是非常特殊的,实际上从不需要。
【解决方案2】:

每次调用时都会更新 mHomeworks 的引用

 mHomeworks = HomeworkLab.get(getActivity()).getHomework();//update list

Java 的垃圾回收会自动回收没有引用它们的对象。因此,如果您没有对旧数组的任何引用,那么它将为您回收。

也就是说,这两行是不需要的:

 mHomeworks.removeAll(mHomeworks);
 mHomeworks = null;

查看@kuntajts 的链接了解更多信息

【讨论】:

    【解决方案3】:

    我会看看这个问题:

    In Java, how is an Array of objects garbage collected?

    基本上我对垃圾回收机制的理解是这样的:

    您对数据有参考吗?

    是的 - 没有 gc。 不 - 做 gc。

    所以在你的情况下这个电话:

    mHomeworks = HomeworkLab.get(getActivity()).getHomework();//update list
    

    会注意删除对旧数据的引用。因此它会自动被 GC 处理。根据我的经验,做你正在做的事情不会明显地帮助或阻碍这个过程。

    【讨论】:

      【解决方案4】:

      当然可以,但 java 确实会处理自己的垃圾收集,并且会在需要更多内存时删除未使用的内存。有关其工作原理的更多信息,请查看:

      How does the Garbage Collection mechanism work?

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-09-05
        • 2016-11-06
        • 1970-01-01
        • 1970-01-01
        • 2019-01-15
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多