一个 Java 方法操作数栈

a Java methods operand stack

最近一直在阅读有关 JVM 内部结构的内容,并对其中的一个元素 - 方法的操作数堆栈有疑问。它有最大尺寸吗?我们可以溢出它吗?我们可以手动完成吗?或者什么条件可能导致它?

每个方法都设置了最大大小,具有 MaxStack 属性。创建更大的操作数堆栈(或不确定大小的操作数堆栈)会导致验证错误,因此从某种意义上说,您不能真正动态地溢出它,它要么是正确的(保持在限制范围内),要么甚至不加载。

由于 MaxStack 属性的类型是 uint16,您可以指定一个操作数堆栈大小,最大为
216-1 个插槽。宽类型占用 2 个槽,与局部变量相同。所以 Java 中的 非常大的 表达式理论上是不可编译的,但实际上 javac 耗尽堆栈 space (实际堆栈 space, 不是操作数栈) 很久之前。

如果属性设置不正确,很容易超过 MaxStack 属性设置的限制,这种情况偶尔会在使用 ClassWriter 时不够小心时发生。