有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

jvm Java VM是在方法末尾始终为空的操作数堆栈

在Java虚拟机中,在方法返回时,操作数堆栈是否仅包含返回值(对于void方法为空)。或者在返回值下是否有其他值需要在堆栈中丢弃

我正在标准C堆栈上创建每个方法框架。如图所示:

enter image description here

如您所见,调用者中的操作数堆栈成为被调用者帧中的参数。 在被调用方帧中,在还原保存的寄存器之前,是否需要清除操作数堆栈上的“垃圾”(返回值除外)


共 (3) 个答案

  1. # 1 楼答案

    ^{}的文件:

    operand stack

    ... → [empty]

    Description

    … If no exception is thrown, any values on the operand stack of the current frame (§2.6) are discarded.

    ^{},分别为:

    operand stack

    ..., value → [empty]

    Description

    … If no exception is thrown, value is popped from the operand stack of the current frame (§2.6) and pushed onto the operand stack of the frame of the invoker. Any other values on the operand stack of the current method are discarded.

    我认为,这提供了足够的提示,操作数堆栈上可能存在必须“丢弃”的值,尽管在典型实现中,不需要采取任何行动,因为丢弃堆栈帧作为一个整体意味着丢弃操作数堆栈

    我不知道为什么这对你来说是个障碍。如果您真的想使用当前操作数堆栈位置到达堆栈帧的开头,您仍然需要有关堆栈帧的元信息,即您必须知道该帧中局部变量的数量。检索此信息并计算堆栈帧开始,不会比首先检索帧开始便宜

  2. # 2 楼答案

    部分答案:operand stack是框架的一部分:

    Each frame (§2.6) contains a last-in-first-out (LIFO) stack known as its operand stack.

    和帧创建/销毁corresponds to方法调用/完成

    A new frame is created each time a method is invoked. A frame is destroyed when its method invocation completes, whether that completion is normal or abrupt (it throws an uncaught exception).

    当一个方法返回时,这并不能提供关于操作数堆栈的更多信息,但至少它回答了您关于需要清理操作数堆栈的问题:因为它是帧本地的,所以不需要清理,因为操作数堆栈与其帧一起被丢弃

  3. # 3 楼答案

    这个问题很难做出结论性的回答,因为你没有明确说明你在问什么

    本规范可公开获取https://docs.oracle.com/javase/specs/jvms/se8/jvms8.pdf(见第2.6.2章)

    这表明堆栈可能处于任意状态,至少在发生未捕获异常时是如此。我没有看到明确提到返回值,但由于返回字节码被指定为从堆栈值返回值,因此必须在堆栈上(第3.5章)

    规范只是对逻辑上发生的事情的描述。真正的VM不需要将规范1:1转换为内存布局——它只需要确保生成的逻辑是相同的(想想JIT代码)