Java的新关键字是否必然表示堆分配?

时间:2013-05-12 09:30:18

标签: java memory heap allocation

我正在尝试快速编写内容,并且不断分配和释放内存,这使得内存在性能方面的分配非常重要。

分配对象是否总是将它们分配给堆? JIT编译是否可以进行任何类型的奇特分配优化?

2 个答案:

答案 0 :(得分:9)

使用new分配的对象放在堆上,但JIT / JVM 可能使用转义分析优化它们以进行堆叠。详细了解in this article published on IBM developerWorks

  

虚拟机可以使用一种称为逃逸分析的技术,通过该技术,他们可以判断某些对象在其整个生命周期内仍然局限于单个线程,并且该生命周期受给定堆栈帧的生命周期的限制。可以在堆栈而不是堆上安全地分配这些对象。

您无法直接控制堆栈分配,就像无法预测何时运行GC一样。如果你真的需要对内存机制进行如此深入的控制,那么唯一的方法就是使用C / C ++。

无论如何,在过度复杂你的软件之前要三思而后行。我上面链接的论文的结论非常清楚内存管理:

  

JVM非常擅长弄清楚我们曾经认为只有开发人员可以知道的事情。通过让JVM根据具体情况在堆栈分配和堆分配之间进行选择,我们可以获得堆栈分配的性能优势,而不会让程序员痛苦地决定是在堆栈上还是在堆上进行分配。

这并不意味着您永远不需要对内存进行细粒度控制,但在大多数情况下,JVM可以比普通程序员更好地进行优化。

答案 1 :(得分:2)

JLS说new分配一个新对象。 JLS 12.5:

  

“当评估类实例创建表达式(第15.9节)导致实例化类时,显式创建了一个新的类实例。”

JLS没有说明对象的分配位置。如果编译器可以推断(通过转义分析)可达性规则允许在堆栈上分配对象,那么这是允许的。

JLS通常被读作允许优化,通过观察执行程序的结果无法检测到其效果。显然,Java 7的最新版本,其中一个优化包括优化异常创建/抛出/捕获代码并用无条件跳转语句(或类似的......)替换它。在某些情况下,此优化涉及优化显式new语句。

总之,new表达式通常导致堆分配,但有时对象在堆栈上分配,有时< / em>分配完全被优化掉了。