循环期间堆栈会发生什么?

时间:2013-04-11 17:44:42

标签: java stack

调用方法时,JVM知道要为其分配多少空间。

但如果我有这样的代码:

while(someCondition) {
   Path p = someMethodThatReturnsAPath();
    //do some things
}

堆栈上发生了什么? 这是怎么回事?:

  • 列表它会在堆栈上创建一个指向指针的指针(指向从方法返回的路径的指针)
  • 完成了一些事情
  • 从堆栈中删除
  • p或“指向Path对象的指针”
  • 重复

上述代码之间是否存在任何(即使它很小)性能差异:

Path p = null;
while(someCondition) {
    p = someMethodThatReturnsAPath();
    //do some things
}

2 个答案:

答案 0 :(得分:1)

这取决于。如果你关闭热点,那么可能会有一个小的性能差异,事情的行为将与你期望的方式相同。随着Hotspot的推出,现代JVM通常使用一组分层编译器来动态优化代码。通常,JVM开始解释,然后在方法的这么多次迭代之后(包括方法中的循环),然后该方法将在后台线程中进行优化,并在某些时候与解释版本交换出来。然后在其他触发器上可能发生更多优化,或者由于新信息而必须恢复。如果JVM可以证明它不起作用并且没有副作用,或者循环可能会展开,你可能会发现循环中对方法的调用完全消失。

告诉正在发生的事情的一个好方法是添加一些JVM标志。以下标志将告诉您何时优化方法-XX:+ PrintCompilation(并在此处记录https://gist.github.com/rednaxelafx/1165804#file_notes.md)和-XX:+ UnlockDiagnosticVMOptions -XX:+ PrintAssembly将为您提供生成的汇编代码C1和C2编译器启动。

答案 1 :(得分:0)

方法所需的所有堆栈都在进入方法时分配,并在离开时取消分配。查看生成的字节码。没有与进入或离开内部块相对应的字节码指令。局部变量的字节码只是按编号引用现有的堆栈槽。

因此,指针永远不会从堆栈中删除。堆栈槽可能会被内部块范围之外的后续声明重用:这是另一回事。

请注意,HotSpot不会在任何地方进入,与其他答案和评论相反。 HotSpot无法优化不存在的指令。 (但它可以消除确实存在的代码。)