我理解单一职责原则的重要性,但从技术上讲,我们是否对每个 java 方法中的局部变量(存储在堆栈帧中)的数量有任何上限。并且该上限是否等于最大堆栈大小,即,我可以有一个大小等于配置的最大堆栈大小的堆栈帧吗?
3 回答
定义局部变量的数量没有上限。如果您定义了太多无法放入堆栈帧的变量(或)JVM 无法为该大小分配堆栈帧,它将抛出StackOverflowError
并退出。
斯坦福教授的演讲很好,可能会对您有所帮助。
这实际上将由您的运行时以及每个进程分配多少堆栈空间来定义。
我对这个明确的问题缺乏直接的答案感到惊讶,所以这里是:JVM 的最大帧大小为 65535 个本地,最大堆栈大小为 65535,long
每个double
条目消耗 2 个插槽。来自 JVM 规范4.11。Java 虚拟机的限制:
在调用方法(第 2.6 节)时创建的帧的局部变量数组中的最大局部变量数被 Code 属性(第 4.7.3 节)的 max_locals 项的大小限制为 65535,给出了代码方法,并通过 Java 虚拟机指令集的 16 位局部变量索引。
请注意,long 和 double 类型的值都被认为保留了两个局部变量并为 max_locals 值贡献了两个单位,因此使用这些类型的局部变量进一步降低了这个限制。
帧中操作数堆栈的大小(第 2.6 节)被 Code 属性的 max_stack 字段限制为 65535 个值(第 4.7.3 节)。
请注意,long 和 double 类型的值都被认为对 max_stack 值贡献了两个单位,因此在操作数堆栈上使用这些类型的值会进一步降低此限制。
理论上,Java 语言可以通过将本地变量和堆栈卸载到堆中来解决这个 JVM 限制(因为这可能会更大),但实际上它并不是真的 - javac
(至少从 Java 15 开始)如果出现错误就会出错您有 65535 个本地人或深度为 65535 的堆栈。