我到处寻找,找不到可靠的答案.根据文档,Java 在以下情况下抛出java.lang.StackOverflowError错误:
在发生堆栈溢出时抛出,因为应用程序过于严重.
但这提出了两个问题:
是否有其他方法可以发生堆栈溢出,而不仅仅是通过递归?
StackOverflowError是否在JVM实际溢出堆栈之前或之后发生?
详细说明第二个问题:
当Java抛出StackOverflowError时,你能安全地假设堆栈没有写入堆中吗?如果你在一个抛出堆栈溢出的函数的try/catch中缩小堆栈或堆的大小,你能继续工作吗?这记录在哪里?
答案我不是在寻找:
由于错误的递归而发生StackOverflow.
当堆遇到堆栈时发生StackOverflow.
JB Nizet.. 195
您可能认为堆栈溢出错误就像本机程序中的缓冲区溢出异常,当存在写入尚未为缓冲区分配的内存的风险时,从而破坏其他一些内存位置.事实并非如此.
JVM具有为每个线程的每个堆栈分配的给定内存,并且如果尝试调用方法恰好填充此内存,则JVM会抛出错误.就像你试图在长度为N的数组的索引N处写一样.没有内存损坏可能发生.堆栈无法写入堆.
StackOverflowError是堆栈OutOfMemoryError对堆的唯一信号:它只是表示没有更多可用内存.
StackOverflowError:Java虚拟机实现已经耗尽了线程的堆栈空间,通常是因为执行程序中的错误导致线程正在执行无限数量的递归调用.
只是一个约会,java.lang.StackOverflowError是一个错误,像OutOfMemory,并不是一个例外.错误和异常扩展Thowable.捕获Error/throwable而不是Exception是一个非常糟糕的问题. (26认同)
@ntoskrnl:是的:http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-2.html#jvms-2.5.2 (4认同)
你得到了所有其他答案的答案.无论您如何处理这种情况,堆栈已满时都会收到错误.但是,鉴于堆栈的大小,我从未见过没有递归的情况. (2认同)
HotSpot具有可靠且安全的堆栈溢出检测,但我想知道JVM规范是否规定了这种行为? (2认同)
Ingo.. 52
是否有其他方法可以发生堆栈溢出,而不仅仅是通过递归?
当然.只需保持调用方法,而不必返回.但是,除非你允许递归,否则你需要很多方法.实际上,它没有什么区别:堆栈帧是堆栈帧,无论它是否是递归方法之一都是相同的.
第二个问题的答案是:当JVM尝试为下一次调用分配堆栈帧时检测到stackoverflow,并发现它不可能.所以,什么都不会被覆盖.