在Java中,新旧本地之间是否存在性能差异?

时间:2011-03-18 14:11:35

标签: java performance garbage-collection new-operator

在C和C ++中我知道在堆栈上实例化对象与使用'new'在堆上创建它们之间的性能可能会有很大差异。

Java中是否相同?

Java中的'new'操作符非常方便(特别是当我不必记住释放/删除使用'new'创建的对象时),但这是否意味着我可以使用'new'? / p>

6 个答案:

答案 0 :(得分:6)

嗯,java中没有其他方法来实例化对象。

使用new创建所有对象,并在堆上创建所有对象。

当你说

时,在Java中

MyObject foo;

您只是声明一个变量(引用)。直到你说

才会实例化
foo = new MyObject();

当对该对象的所有引用超出范围时,该对象变得易于垃圾收集。你会注意到java中没有delete这样的东西:)

答案 1 :(得分:6)

Java中没有在堆栈上分配对象。

只有局部变量(和参数)可以存在于堆栈中,并且那些只能包含引用或原始值,但绝不能包含对象。

答案 2 :(得分:5)

您无法在堆栈上创建对象,您只能在堆栈上包含基元和引用,因此该问题不适用于Java。

已经尝试使用转义分析来优化短暂的对象(并且可能将它们放在堆栈中)但是我没有看到任何证据表明这种改进的性能。

与C / C ++中的性能命中/利益不同的部分原因是Java在堆上具有线程本地分配,并且对象不会像往常一样被回收。 C / C ++具有线程本地堆栈,但您需要其他库以支持多线程对象分配。物体被更具侵略性地回收,这增加了物体分配的成本。

来自C / C ++世界的最大变化之一是发现Java具有更少的功能,但尝试充分利用它们(JVM中有很多复杂的优化)另一方面Java有一个丰富/令人困惑的开源库阵列。

答案 3 :(得分:3)

在我之后重复:在Java中没有在堆栈上分配对象

在Java中,与C ++不同,所有对象都在堆上分配,唯一的出路就是垃圾收集时。

在Java中,与C ++不同,变量超出范围并不意味着对象的析构函数运行;事实上,没有析构函数。所以变量可能会超出范围,但对象在堆上仍然存在。

  

我可以和'新'一起疯狂吗?

是。首先,因为它是实例化对象的唯一方法。其次,因为JVM非常好,它可以在不到一秒的时间内创建最多2 ^ 32个重量级的对象。

答案 4 :(得分:1)

在Java中,无法在堆栈上手动分配对象,尽管编译器可能决定在堆栈上分配使用“new”创建的对象,请参阅Java theory and practice: Urban performance legends, revisited

答案 5 :(得分:0)

这里真的无法比较:你无法在Java中创建堆栈中的对象。

但是,如果它是任何舒适,Java 中基于堆的分配(至少通常)非常快。 Java的垃圾收集器定期“清理”堆,因此它基本上看起来很像堆栈,从它分配就像分配堆栈一样 - 在典型的情况下,你有一个指向开头的指针(或者结束一个空闲的内存区域,并且分配一块内存只是意味着从该指针添加(或减去)数量,并返回开头的地址(当然,然后在那里构造一个或多个对象)区域等。)