我理解单一职责原则的重要性,但从技术角度来看,我们在每个Java方法中存储在堆栈帧中的局部变量数量是否有上限?并且这个上限是否等于最大堆栈大小?也就是说,我可以拥有一个大小等于最大堆栈大小配置的堆栈帧吗?
long
和 double
每个占用两个条目。参考 JVM 规范 4.11. Java 虚拟机的限制:
在调用方法(§2.6)时创建的帧的局部变量数组中的局部变量数目最多为 65535,由 Code 属性(§4.7.3)(给出该方法的代码)的 max_locals 项大小以及 Java 虚拟机指令集的 16 位局部变量索引限制。
请注意,每个 long 和 double 类型的值都被认为是预留了两个局部变量,并且向 max_locals 值贡献了两个单位,因此使用这些类型的局部变量会进一步降低此限制。
帧中操作数栈的大小(§2.6)受 Code 属性(§4.7.3)的 max_stack 字段限制,最多可以达到 65535。
请注意,每个 long 和 double 类型的值都被认为向 max_stack 值贡献了两个单位,因此在操作数栈中使用这些类型的值会进一步降低此限制。
理论上来说,Java 语言可以通过将局部变量和堆栈卸载到堆中(因为堆可以更大)来解决 JVM 的限制问题,但在实践中它并没有真正做到-javac
(至少截至 Java 15)会在您拥有 65535 个本地变量或堆栈深度为 65535 时报错。
在定义本地变量数量时没有上限。如果您定义了太多无法放入堆栈帧中(或者)JVM无法为其大小分配堆栈帧,则会抛出StackOverflowError
并退出。
有一位斯坦福教授的好讲座可能会对您有所帮助。