gpt4 book ai didi

java - Java 字节码中的堆栈=4。 Java 编译器如何计算 4 值? (栈的深度)

转载 作者:行者123 更新时间:2023-12-02 08:53:27 24 4
gpt4 key购买 nike

Java 代码:

public class SimpleRecursion {

public int factorial(int n) {
if (n == 0) {
return 1;
}
return n * factorial(n - 1);
}

}

为阶乘方法提供以下字节码(我执行 javap 来生成它):

public int factorial(int); 
descriptor: (I)I
flags: ACC_PUBLIC
Code:
stack=4, locals=2, args_size=2
0: iload_1
1: ifne 6
4: iconst_1
5: ireturn
6: iload_1
7: aload_0
8: iload_1
9: iconst_1
10: isub
11: invokevirtual #2 // Method factorial:(I)I
14: imul
15: ireturn
LineNumberTable:
line 4: 0
line 5: 4
line 7: 6
StackMapTable: number_of_entries = 1
frame_type = 6 /* same */

据我了解,在上面 block 的第五行中,stack=4 表示堆栈最多可以有 4 个对象

但是编译器如何计算呢?

最佳答案

由于堆栈的初始状态以及每条指令对其的影响是众所周知的,因此您可以精确地预测任何时候操作数堆栈上将包含哪些类型的项目:

[ ]            // initially empty
[ I ] 0: iload_1
[ ] 1: ifne 6
[ I ] 4: iconst_1
[ ] 5: ireturn
[ I ] 6: iload_1
[ I O ] 7: aload_0
[ I O I ] 8: iload_1
[ I O I I ] 9: iconst_1
[ I O I ] 10: isub
[ I I ] 11: invokevirtual #2 // Method factorial:(I)I
[ I ] 14: imul
[ ] 15: ireturn

JVM 的 validator 正是这样做的,预测每条指令后堆栈的内容,以检查它是否适合作为后续指令的输入。但它在这里有帮助,有一个声明的最大大小,因此验证者不需要维护动态增长的数据结构或为理论上可能的 64k 堆栈条目预分配内存。使用声明的最大大小,当遇到超出该大小的指令时,它可以停止,因此它永远不需要比声明的内存更多的内存。

正如您所看到的,声明的最大堆栈大小恰好达到一次,就在索引 9 处的 iconst_1 指令之后。

然而,这并不意味着编译器必须执行这样的指令分析。编译器具有从源代码派生的代码的更高级别模型,称为 Abstract syntax tree .

该结构将用于生成生成的字节码,并且它还可以预测该级别所需的堆栈大小。但编译器实际上如何做到这一点取决于实现。

关于java - Java 字节码中的堆栈=4。 Java 编译器如何计算 4 值? (栈的深度),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54342508/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com