【发布时间】:2012-12-09 08:57:01
【问题描述】:
为了估计递归方法在给定内存量下可以实现的最大调用深度,计算在可能发生堆栈溢出错误之前使用的内存的(近似)公式是什么?
编辑:
很多人的回答是“它取决于”,这是合理的,所以让我们通过一个琐碎但具体的例子来删除一些变量:
public static int sumOneToN(int n) {
return n < 2 ? 1 : n + sumOneToN(n - 1);
}
很容易证明,在我的 Eclipse IDE 中运行它会爆炸,n 不到 1000(对我来说太低了)。
是否可以在不执行的情况下估计此调用深度限制?
编辑:我不禁想到 Eclipse 有一个固定的最大调用深度 1000,因为我得到了998,但是有一个用于主方法,一个用于方法的初始调用,使@987654325 @ 在所有。这是一个“太圆”的数字恕我直言,不是巧合。我会进一步调查。我刚刚 Dux 开销了 -Xss vm 参数;这是最大堆栈大小,因此 Eclipse 运行器必须在某处设置 -Xss1000
【问题讨论】:
-
(这似乎取决于 JVM 和可能的架构。)
-
我猜这只是局部变量+帧指针+返回地址。
-
我也觉得不测量是无法估计的
-
递归实际上与此无关(除了它是生成非常深的调用堆栈的最常用方法)。出于确定调用深度限制的目的,递归调用与任何其他类型的调用没有什么不同。 (当然,编译器可能会消除尾递归,在这种情况下,递归会主动分散您的问题。)
标签: java memory recursion jvm stack-overflow