是否有可能强制JVM创建堆栈以外的堆对象?

问题描述:

我读了一些地方,有时JVM会识别一些对象,并尝试在堆栈中创建它,而不是堆栈,因为堆栈上的内存分配比堆中的内存分配要便宜,堆栈上的重新分配是免费的,堆栈是有效的由运行时管理。 那么这个对象在堆栈中的分配是如何工作的,并且有什么办法强制JVM来做到这一点?是否有可能强制JVM创建堆栈以外的堆对象?

+1

没有人无法控制JVM的选择放置策略。持久数据不能放置在堆栈上,因为堆栈上的数据将在执行某些类后被释放。 – 2014-08-29 04:42:35

+0

仅供参考:http://www.stefankrause.net/wp/?p = 64 – 2014-08-29 04:52:23

+0

请注意,即使堆栈分配最终发生,它也只会将代码路径检测为“热”并且值得JIT编译。 – 2014-08-29 04:55:36

无法强制JVM在任何地方分配对象。您不应该关心Java实际分配对象的位置,因为它没有在规范中定义。这就是说,JVM已经变得更加智能,并且使用了一种叫做escape analysis 的技术,如果它愿意的话,它可以在堆栈上分配一个对象。然而,没有办法强制JVM在特定的地方分配对象,规范并不要求这种行为发生。

如果谈论HotSpot JVM,它永远不会在堆栈上分配Java对象。然而,有一个优化:当Escape Analysis可以证明一个对象引用不会转义正在编译的作用域时,JIT根本不会使用分配,并用局部变量替换对象字段。

注意:由于对象不存在,所以我们不能声称这是堆栈上的分配,例如,调用Object的方法如hashCodewait是不可能的。

只要JVM可以消除分配,它就会自动执行。
如果它不能 - 无法强制它。

+0

你的注释是错误的:我们可能很好地在对象上调用'hashCode',甚至是'wait',它对Escape Analysis没有什么影响,因为EA需要确定*无论如何*确切的对象类型规则堆栈分配。当你知道确切的对象类型时,你可以内联所有的方法调用,当你这样做时,你可以让他们的实现引用堆栈位置。 – 2014-08-29 06:46:15

+0

顺便说一句,在一个非转义对象上的wait(timeout)可以作为简单的'sleep(timeout)'来实现。类似的事情可以为无参数'wait()'调用 - 无限阻塞完成。 – 2014-08-29 06:48:29

+0

@MarkoTopolnik你的理论假设是正确的,但我现在谈论具体实现,即HotSpot JVM。那么,抽象的JVM可以在任何地方和任何地方分配对象,但是如果引用了对象头,HotSpot不会消除分配。 – apangin 2014-08-29 08:50:08