什么是Java中的StackOverflowError?它在什么情况下发生?

5
有人能告诉我 Java 中的 StackOverflowError 是什么吗?

15
给我力量。 - Mitch Wheat
4
@Mitch:SO不是一个用来询问你不理解的编程问题的地方吗? - T.J. Crowder
3
@Mitch,对我来说这似乎是一个完全有效的问题。诚然它很基础,但我们都曾经是初学者。 - Dónal
2
SO并不是“专家专用”,但可以合理地期望人们首先尝试搜索一些内容。 - Jesper
1
好的,也许我的评论有些不公正,但似乎搜索很快就能回答这个问题。 - Mitch Wheat
显示剩余6条评论
5个回答

17

堆栈溢出是指当放置在堆栈中的数据过多时,会超出该有限资源的容量。

以下是一个示例:

public class Overflow {
    public static final void main(String[] args) {
        main(args);
    }
}

该函数没有终止条件地反复调用自身。因此,由于每次调用都必须在堆栈上推送返回地址,堆栈会填满,但由于该函数永远不会返回,因此返回地址从未弹出堆栈,它只是不断地调用自身。


9
在Java中不存在“StackOverFlowException”的东西。
但是,存在一个名为“StackOverflowError”的类,文档指出:
当应用程序递归太深导致堆栈溢出时抛出该异常。
如果你不知道什么是堆栈,请阅读此调用栈

2
@Don:请不要删除我的回答的一部分。我已经撤销了你的删除操作。 - Jesper
我删除了它,因为我还改变了问题,所以你的答案的一部分不再有意义了。 - Dónal
当我使用新对象创建无限循环时,为什么不会出现错误? - rolling stone

4
每次调用函数时,都会为其分配一个特殊内存区域(栈)的一小段,并保存该函数的局部变量和上下文。如果我们的函数调用另一个函数,则下一段将被切断并放入栈中等待处理。当函数再次返回时,栈将缩小。如果嵌套层次过多,可能会导致栈溢出。
这是一个非常通用的概念。在Java中,当超出栈大小限制时,会抛出一个StackOverflowError错误。这是一个错误而不是异常,因为您需要避免此情况,而不是从中恢复。
典型的例子是无限递归:
public void foo(int i) {
  return foo(i+1);
}

0
通常情况下,当递归方法被调用太多次时。例如:
public void doSomething(int time)
{
  System.out.println("do #" + (doSomething(time++)));
}

-2
Java虚拟机会为你的程序分配一定数量的内存。如果你的程序使用了太多的内存,就会出现错误。上面的例子很好,但是如果你试图创建一个非常大的数组,也可能导致溢出。 你可以通过使用命令行参数来为你的程序分配更多的内存(例如200MB)。
java -Xmx200m YOUR_PROGRAM_CLASS

这将降低您获得StackOverFlow异常的机会。

这解释了命令行选项

(http://java.sun.com/j2se/1.4.2/docs/tooldocs/windows/java.html#Xms)


1
-1:即使有很多堆内存,也可能会发生StackOverflowError。 - Santhosh Kumar Tekuri
然而错误的根本原因仍然相同,即过多的内存。您可以通过增加堆大小或更有效地使用内存来解决它。 - Opal

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接