Each Java Virtual Machine thread has a private Java Virtual Machine
stack, created at the same time as the thread. A Java Virtual Machine
stack stores frames (§2.6). A Java Virtual Machine stack is analogous
to the stack of a conventional language such as C: it holds local
variables and partial results, and plays a part in method invocation
and return. Because the Java Virtual Machine stack is never
manipulated directly except to push and pop frames, frames may be heap
allocated. The memory for a Java Virtual Machine stack does not need
to be contiguous.
In the First Edition of The Java® Virtual Machine Specification, the
Java Virtual Machine stack was known as the Java stack.
This specification permits Java Virtual Machine stacks either to be of
a fixed size or to dynamically expand and contract as required by the
computation. If the Java Virtual Machine stacks are of a fixed size,
the size of each Java Virtual Machine stack may be chosen
independently when that stack is created.
A Java Virtual Machine implementation may provide the programmer or
the user control over the initial size of Java Virtual Machine stacks,
as well as, in the case of dynamically expanding or contracting Java
Virtual Machine stacks, control over the maximum and minimum sizes.
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
StackOverflowError.
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.
由于您没有提供堆栈大小,JVM 会尝试动态扩展堆栈大小,因为递归调用函数需要更多堆栈内存。在每次运行中,它可能会为其堆栈找到不同数量的动态内存,具体取决于运行时计算机上的内存可用性。这就是您在抛出 SO 错误之前看到不同迭代次数值的原因。如果您为程序配置(使用 Xss<size>
JVM 参数)较小的堆栈大小,您应该会在 SO 错误之前看到几乎相同的递归数。