什么更有效?清空一个对象或创建一个新对象?

时间:2012-02-16 15:37:31

标签: java list memory-management new-operator memory-efficient

'新'有多贵?我的意思是,如果我的目标是重复使用同一个对象,或者如果对象是“超出范围”,那么它与清空它是一样的吗?

示例,假设一个方法创建一个列表:

List<Integer> list = new ArrayList<Integer>(); 

在方法结束时,列表不再使用 - 它是否意味着没有分配给它的内存,或者它是否意味着有一个指向它的空指针(因为它是'创建')。

或者,我可以向方法发送一个'list'并在方法的末尾清空它:list.removeAll(list);这会从内存的角度来看有什么不同吗?

谢谢!

6 个答案:

答案 0 :(得分:15)

它是一个数组列表,因此创建一个新对象意味着分配一块内存并将其归零,以及任何簿记开销。清除列表意味着清零存储器。此视图将使您相信清除现有对象更快。但是,JVM可能会进行优化以快速进行内存分配,因此这些都不重要。所以只需编写清晰易读的代码,不要担心。毕竟这是java,而不是c。

答案 1 :(得分:3)

在方法结束时列表不再使用 - 它是否意味着没有分配给它的内存或它是否意味着它有一个空指针(因为它是'创建') 。

表示没有对它的引用,对象符合GC的条件。

或者,我可以向方法发送一个'list',并在方法的末尾清空它:list.removeAll(list);会从记忆的角度来看会有什么不同吗?

它是时间/空间之间的权衡。即使您不需要创建新对象,从列表中删除元素也很耗时。

使用最新的JVMs GC集合功能,可以在需要时创建新对象(但最好避免在循环中创建对象)。对对象的较长引用有时会使该对象不符合GC的条件,如果处理不当,可能会导致内存泄漏。

答案 2 :(得分:2)

我对java中的内存占用情况了解不多,但我认为清空一个List来重用它,并不是一个好主意,因为清空List会影响性能。而且我认为这也是一个OO视角并不是一个好主意,因为你应该有一个只有一个目的的对象。

在方法结束时,对象确实超出了范围。但这并不意味着它是垃圾收集甚至是垃圾收集资格,因为其他人可能仍然引用该List。所以基本上:如果没有对该列表的对象引用那么它可能是垃圾收集的简单,但如果它将被垃圾收集它仍然不确定,如果列表仍然存储在Young Generation空间中它可以在伊甸园空间或终身空间。 Eden空间是首先分配对象的地方,当垃圾收集发生且对象仍然存在时,它将被移动到幸存者空间。如果它仍然存活过去,那么它将转移到Tenured空间,我相信垃圾收集不会发生。但这一切都取决于一个物体存在多长时间,谁引用这个物体以及它被分配的地方

答案 3 :(得分:2)

  

“新”有多贵?

肯定会产生一些开销。但这取决于对象的复杂程度。如果你用一些原语创建一个对象,那就不那么贵了。但是如果要在对象内部创建对象,则可能是对象集合,如果构造函数正在读取某些属性文件以初始化对象的成员变量,则为EXPENSIVE!

但坦率地说,如果我们 需要 创建一个新对象,我们 创建它,没有替代。如果我们不需要,如果我们仍然在创造那种糟糕的编程。

  

在方法结束时,列表不再使用 - 这是否意味着   没有内存分配给它或它是否意味着   有一个指向它的空指针(因为它是'创建')。

一旦对象没有对它的任何引用,它就会超出范围,并且它有资格进行垃圾回收。因此,即使它分配了一些内存,GC也会在稍后的某个时间点回收它,无论何时运行,我们都不用担心它。 (我们无法保证GC何时运行)。

最后清空集合,我认为不会让事情变得更好,因为集合中的所有单个对象都会发生同样的事情,就像集合本身会发生什么一样。他们将有资格参加GC。

答案 4 :(得分:2)

对于小型列表,clear()列表可能会便宜一些。

对于真正大型堆中真正大型列表的渐近情况,可以归结为GC是否可以比for中的clear()循环更快地将大块内存归零。而且我认为它可能会。

但是,我的建议是忽略这一点,除非你有令人信服的证据(来自分析)你有ArrayList个对象的高转换率。 (根据你的直觉进行优化是一个坏主意。)

答案 5 :(得分:2)

这取决于对象的成本,无论是初始化要求还是内存占用量都有多大。它还在很大程度上取决于应用程序的类型(应用程序还需要花费的时间)。

对于使用ArrayList的示例,它已经非常难以给出明确的答案 - 取决于列表中有多少条目,clear()可能非常昂贵或非常便宜,而新的ArrayList几乎不变成本。

一般的经验法则是:在测量表示存在性能问题之前,不要再重复使用对象,然后非常确定创建对象是导致该问题的原因。很可能在您的应用程序中有更多有益的优化机会。分析器将帮助您确定花费最多时间的地方。专注于那些和更好的algoryhtms。