我到处找都找不到确切的答案。根据文档,Java在以下情况下抛出Java .lang. stackoverflowerror错误:

当由于应用程序递归太深而发生堆栈溢出时引发。

但这引发了两个问题:

除了通过递归,没有其他方法可以导致堆栈溢出吗? StackOverflowError发生在JVM溢出堆栈之前还是之后?

关于第二个问题:

当Java抛出StackOverflowError时,您是否可以安全地假设堆栈没有写入堆?如果您在抛出堆栈溢出的函数的try/catch中缩小堆栈或堆的大小,您可以继续工作吗?这在任何地方都有记录吗?

我不想要的答案:

发生StackOverflow是由于糟糕的递归。 当堆遇到堆栈时发生StackOverflow。


当前回答

在c#中,可以通过错误地定义对象属性来实现堆栈溢出。 例如:

private double hours;

public double Hours
        {
            get { return Hours; }
            set { Hours = value; }
        }

如你所见,它会一直返回带有大写H的Hours, H本身也会返回Hours,等等。

堆栈溢出也经常发生,因为内存不足,或者当使用托管语言时,因为您的语言管理器(CLR, JRE)将检测到您的代码陷入无限循环。

其他回答

除了通过递归,没有其他方法可以导致堆栈溢出吗?

当然。只需要继续调用方法,而不返回。不过,您将需要很多方法,除非您允许递归。实际上,这并没有什么区别:一个堆栈框架就是一个堆栈框架,不管它是不是递归方法之一都是一样的。

第二个问题的答案是:当JVM试图为下一个调用分配堆栈帧时,发现不可能分配堆栈帧,就会检测到stackoverflow。所以,没有东西会被覆盖。

在c#中,可以通过错误地定义对象属性来实现堆栈溢出。 例如:

private double hours;

public double Hours
        {
            get { return Hours; }
            set { Hours = value; }
        }

如你所见,它会一直返回带有大写H的Hours, H本身也会返回Hours,等等。

堆栈溢出也经常发生,因为内存不足,或者当使用托管语言时,因为您的语言管理器(CLR, JRE)将检测到您的代码陷入无限循环。

StackOverflow发生在函数调用时,堆栈已满。

就像一个ArrayOutOfBoundException。它不会腐蚀任何东西,事实上很有可能抓住它并从中恢复。

它通常是由于不受控制的递归导致的,但也可能是由于调用了非常深的函数堆栈而导致的。

由于应用程序递归太深而发生StackOverflowError(这不是您期望的答案)。

现在其他的事情发生在StackOverflowError是从方法一直调用方法,直到你得到StackOverflowError,但没有人可以编程得到StackOverflowError,即使那些程序员是这样做的,然后他们没有遵循编码标准的圈的复杂性,每个程序员都必须理解,而编程。这样的原因'StackOverflowError'将需要很多时间来纠正它。

但不知不觉地编码一行或两行导致StackOverflowError是可以理解的,JVM抛出,我们可以立即纠正它。这是我对其他一些问题的回答。

Java中有两个主要的存储位置。第一个是Heap,用于动态分配对象。新的。

此外,每个运行的线程都有自己的堆栈,并获得分配给该堆栈的一定数量的内存。

当您调用一个方法时,数据将被推入堆栈以记录方法调用、传入的参数和分配的任何局部变量。具有五个局部变量和三个参数的方法将比没有局部变量的void doStuff()方法使用更多的堆栈空间。

堆栈的主要优点是没有内存碎片,一个方法调用的所有内容都分配在堆栈顶部,并且从方法返回很容易。要从一个方法返回,只需将堆栈展开到前一个方法,为返回值设置所需的任何值,就完成了。

Because the stack is a fixed size per thread, (note that the Java Spec does not require a fixed size, but most JVM implementations at the time of writing use a fixed size) and because space on the stack is needed whenever you make a method call hopefully it should now be clear why it can run out and what can cause it to run out. There isn't a fixed number of method calls, there isn't anything specific about recursion, you get the exception which you try to call a method and there isn't enough memory.

当然,堆栈的大小设置得足够高,以至于在常规代码中不太可能发生这种情况。在递归代码中,递归很容易深入到很深的地方,这时你就会遇到这个错误。