JAVA STACK 何时会在 STACK 中抛出 OOM 错误而不是 SOF 错误?

When will JAVA STACK throw OOM Error instead of SOF Error, in STACK?

我了解到 OutOfMemoryError 和 WhosebugError 都可能在堆栈中发生。 但是不知道什么时候会把OOM扔进stack?

在堆栈中创建新对象时是否抛出?那我估计这个新对象不属于栈帧,否则会抛出SOF

非常感谢您的回答。我搜索了 google 但没有找到相关答案。

对于之前不清楚的缩写,我深表歉意!!

我相信你在谈论 OutOfMemoryError 和 WhosebugError。

  • OutOfMemoryError 当堆中没有更多空闲 space 用于分配新对象时发生。 space 的其余部分被强引用对象占用。垃圾回收无法回收 space 那些对象 space。对象和数组总是分配在堆中,而不是堆栈中。 (ScapeAnalysis/Scalarreplacement/JIT可能是个例外)

  • Whosebug 发生在 jvm 堆栈中没有空闲 space 时。堆栈存储局部方法变量和 frames,它们在每次方法调用时创建(例如通常的错误堆栈跟踪)。

您可以在 JVM 规范中阅读有关堆和堆栈的更多详细信息。

我强烈建议减少不必要的缩写使用。虽然很明显“OOM”指的是 OutOfMemoryError,但“EOF”和“SOF”的含义不是。 “EOF”通常是指“文件结尾”,此处不适用。 “SOF”可以指代 Whosebug,但这很不寻常。我不认为写错误的全名会占用你太多的时间。

关于 OutOfMemoryError,答案是它取决于实现。

JVM 规范§2.5.2. Java Virtual Machine Stacks

The following exceptional conditions are associated with Java Virtual Machine stacks:

  • If the computation in a thread requires a larger Java Virtual Machine stack than is permitted, the Java Virtual Machine throws a WhosebugError.
  • If Java Virtual Machine stacks can be dynamically expanded, and expansion is attempted but insufficient memory can be made available to effect the expansion, or if insufficient memory can be made available to create the initial Java Virtual Machine stack for a new thread, the Java Virtual Machine throws an OutOfMemoryError.

所以原则上,在某些情况下可以抛出 OutOfMemoryError,但广泛使用的 HotSpot JVM 不支持动态堆栈扩展,因此这永远不会成为 OutOfMemoryError 的原因。

创建新的 Thread 可能会失败并出现 OutOfMemoryError,但由于涉及多个分配,包括堆上的 Thread 实例,因此是否无关紧要失败的分配应该提供新线程的堆栈内存或用于其他目的。