一尘不染

究竟是什么导致堆栈溢出错误?

java

我到处都是,找不到可靠的答案。根据文档,在以下情况下,Java引发java.lang.StackOverflowError错误:

由于应用程序递归过深而在堆栈溢出时抛出。

但这提出了两个问题:

  • 不仅通过递归,还有其他方法可以使堆栈溢出吗?
  • 是在JVM实际溢出堆栈之前还是之后发生StackOverflowError?

详细阐述第二个问题:

当Java引发StackOverflowError时,您是否可以安全地假设堆栈未写入堆中?如果您在尝试引发堆栈溢出的函数中进行尝试/捕获来缩小堆栈或堆的大小,那么您可以继续工作吗?这在任何地方都有记录吗?

我不需要的答案:

  • 由于错误的递归,导致发生StackOverflow。
  • 当堆遇到堆栈时,将发生StackOverflow。

阅读 313

收藏
2020-09-09

共1个答案

一尘不染

似乎您在考虑一个堆栈溢出错误,就像本机程序中的缓冲区溢出异常一样,这是因为存在写入尚未分配给该缓冲区的内存的风险,从而损坏了其他一些内存位置。根本不是这样。

JVM为每个线程的每个堆栈分配了给定的内存,并且如果尝试调用方法的尝试恰好填充了该内存,则JVM会引发错误。就像您尝试在长度为N的数组的索引N处写入时一样。不会发生内存损坏。堆栈无法写入堆。

一个StackOverflowError对于堆栈来说就是一个OutOfMemoryError对堆:它只是表示没有更多可用的内存。

虚拟机错误说明(§6.3)

Java虚拟机实现已为线程耗尽了堆栈空间,通常是由于执行程序中的错误导致线程正在进行无数次的递归调用。

2020-09-09