我目前正在学习Java,作为我学习的一部分,我试图故意引起堆栈溢出,看看它会做什么。
我做了一些边界测试,有趣的是,我发现如果我执行以下代码,它只会偶尔导致错误。有时它会毫无问题地运行。
public class SO
{
public static void main(String[] args)
{
ohno(0);
}
public static void ohno(int a)
{
System.out.println(a);
if (a != 11413)
ohno(a+1);
}
}
我的问题如下:
答案 0 :(得分:3)
有限的堆栈大小是您分配给JVM的内存量的函数。
资源受限的系统具有可以分配的更少内存,因此绝对存在堆栈大小受限制的实际场景,并且有时您必须自然地使用迭代解决方案 - 结果导致的错误问题。
增加系统的物理内存只对您允许JVM分配内存很重要,否则您将获得该平台的默认值。
答案 1 :(得分:1)
发生StackOverflowException的可能性取决于您分配的内存量,使用参数XmxM / G表示最大内存,XmxS / G表示最小内存。
堆栈溢出可能发生在任何情况下,如果存在死循环,或者有可能通过自动循环获得大量数据(这会消耗大量内存)的数据。
答案 2 :(得分:0)
许多编译器检测尾递归调用并为该调用重用相同的堆栈帧,从而防止此类调用增加堆栈。尾递归调用是递归调用是方法或函数中的最后一条指令的调用。此优化允许您使用尾递归而不必担心堆栈溢出。
如果希望引发溢出,请尝试在递归调用后添加一些代码以防止优化。您可能需要稍微玩一下 - 好的编译器很狡猾,可能会破坏简单的尝试。