我到处找都找不到确切的答案。根据文档,Java在以下情况下抛出Java .lang. stackoverflowerror错误:
当由于应用程序递归太深而发生堆栈溢出时引发。
但这引发了两个问题:
除了通过递归,没有其他方法可以导致堆栈溢出吗?
StackOverflowError发生在JVM溢出堆栈之前还是之后?
关于第二个问题:
当Java抛出StackOverflowError时,您是否可以安全地假设堆栈没有写入堆?如果您在抛出堆栈溢出的函数的try/catch中缩小堆栈或堆的大小,您可以继续工作吗?这在任何地方都有记录吗?
我不想要的答案:
发生StackOverflow是由于糟糕的递归。
当堆遇到堆栈时发生StackOverflow。
StackOverFlowError最常见的原因是过度深度递归或无限递归。
例如:
public int yourMethod(){
yourMethod();//infinite recursion
}
在Java中:
内存中有两个区域:堆和堆栈。堆栈内存用于存储局部变量和函数调用,而堆内存用于存储Java中的对象。
如果堆栈中没有剩余内存用于存储函数调用或本地变量,JVM将抛出java.lang.StackOverFlowError
而如果没有更多的堆空间来创建对象,JVM将抛出java.lang.OutOfMemoryError
在c#中,可以通过错误地定义对象属性来实现堆栈溢出。
例如:
private double hours;
public double Hours
{
get { return Hours; }
set { Hours = value; }
}
如你所见,它会一直返回带有大写H的Hours, H本身也会返回Hours,等等。
堆栈溢出也经常发生,因为内存不足,或者当使用托管语言时,因为您的语言管理器(CLR, JRE)将检测到您的代码陷入无限循环。