清空对象和创建一个新对象哪个更高效?

11

'new' 操作有多耗费资源?我的意思是,我应该尽量复用同一个对象,还是当对象不再使用时将其设为空,这样做和复用是一样的吗?

比如说,一个方法创建了一个列表:

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

在方法结束时,该列表不再使用 - 这是指它不再分配内存了,还是指它有一个空指针(因为它被“创建”)。

或者,我可以将一个“列表”发送到方法中,并在方法结束时清空它:list.removeAll(list);从内存角度看,这会有什么区别吗?

谢谢!


4
我认为编写清晰易读的代码更有意义。在 Java 中,你不必担心这种事情。 - Kevin
在某个时刻,不再使用的对象(例如超出作用域)将被JVM自动垃圾回收。如果您想要清理列表,可以这样做,但是JVM最终会为您处理它们。 - Tony
如果你有足够的时间来清空列表,那么你可以这样做。否则绝对不行。 - sgowd
6个回答

15

这是一个ArrayList,因此创建一个新对象意味着分配一块内存并将其清零,以及任何的簿记开销。清除列表意味着将内存清零。这种观点会让你相信清除现有对象会更快。但是,JVM优化使得内存分配变得更快,所以可能这都不重要。因此,只需编写清晰易读的代码,不必担心这些。毕竟这是Java,而不是C。


4

在方法的末尾,列表不再使用 - 这是指它不再分配内存,还是指有一个空指针(因为它被“创建”)。

这意味着没有对它的引用,对象可以进行垃圾回收。

或者,我可以将“列表”发送到该方法,并在方法结束时清空它:list.removeAll(list); 从内存角度来看,这会有什么区别吗?

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

使用最新的JVM GC集合功能,在需要时创建新对象是可以的(但在循环中避免创建对象最好)。对对象的长时间引用有时会使该对象无法进行垃圾回收,并且如果处理不当可能会导致内存泄漏。


2
我对Java内存占用不是很了解,但我认为清空List以重复使用并不是个好主意,因为清空List会对性能造成影响。从面向对象的角度来看也不太好,因为一个对象应该只有一个目的。
在方法结束时,对象确实超出了作用域。但这并不意味着它已被垃圾回收或者是可以进行垃圾回收的,因为其他对象仍然可能引用该List。基本上,如果没有任何对象引用该List,则它可能符合垃圾回收的条件,但即使它被垃圾回收了,如果该List仍然存储在年轻代空间中,它可能同时存在于伊甸园区和终身区。伊甸园区是分配对象的初始位置,当进行垃圾回收时,如果对象仍然存活,将被移动到幸存者空间。如果对象在那里仍然存活,它将移动到终身区,在那里不会发生太多的垃圾回收。但所有这些都取决于对象存活的时间、引用此对象的对象以及其分配位置。

2
“new”有多贵?
这肯定会产生一些开销。但这取决于对象的复杂程度。如果您只创建一个仅包含几个基本类型的对象,那么开销不大。但是,如果您在对象内部创建对象,可能是对象集合,如果您的构造函数正在读取某些属性文件以初始化对象的成员变量,则会很昂贵!
但说实话,如果我们需要创建新对象,那我们就必须创建它,没有其他选择。如果我们不需要创建新对象,而我们仍然在创建,那就是一种糟糕的编程方式。
“方法结束时列表不再使用”- 这是指该列表不再分配任何内存,还是指它有一个空指针(因为它已经"被创建")?
一旦对象没有任何引用指向它,它将变为超出范围,并且将变得符合垃圾收集条件。因此,即使它有一些内存分配,也将在某个稍后的时间点被 GC 回收,我们不必担心它。(我们无法保证 GC 何时运行)。
在方法末尾清空集合并不能使事情变得更好,因为与集合本身发生的事情相同,所有单个对象也将发生。它们将变得符合垃圾收集条件。

2
对于小型列表,使用clear()方法可能会更便宜一些。
对于非常大的列表和堆,关键在于GC能否比clear()方法中的for循环更快地将大块内存清零。我认为它可能做得到。
然而,我的建议是,除非您有令人信服的证据(从分析结果得出),表明您需要高频率地创建和销毁ArrayList对象,否则不要考虑这个问题。(仅凭直觉进行优化是一个坏主意。)

2
这取决于对象初始化所需的成本以及其内存占用大小。它还严重依赖于应用程序的类型(应用程序在其他方面花费了多少时间)。
就您使用ArrayList的示例而言,很难给出一个明确的答案 - 取决于列表中有多少条目,clear()可能非常昂贵或非常便宜,而新的ArrayList几乎具有恒定的成本。
一般的经验法则是:在测量出性能问题之前不要费心去重复使用对象,并确保创建对象是问题的根源。最有可能的是,在您的应用程序中有更有价值的优化机会。分析器将有助于确定您花费最多时间的地方。专注于那些和更好的算法。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接