public class SBtst { int i = 0; public static void main(String[] args) { new SBtst().rec(); } public void rec() { System.out.println("rec is called "+i++); try { rec(); } catch (StackOverflowError soe) { System.out.println("completed "+soe.getStackTrace().length); } } }
执行后,我得到的输出类似于:
rec is called 10472 rec is called 10473 rec is called 10474Recursion completed 1024
问题是:
>为什么没有println()完成新行,因为据了解,当执行下一个rec()调用时,应该抛出一个错误,并且是完成后的println()
>为什么stackTrace数组中只有1024个元素,但是等于10474?这是否意味着并不是每个调用都在堆栈跟踪中?
解决方法
Why didn’t println() complete a new line? As I understand,the exception should be thrown when the next rec() call is executed,but that would be after println() has completed.
你的理解不太正确.在某些时候,堆栈看起来像:
… rec() rec() rec() println()
Println也会消耗资源(参见mattingly890’s answer),没有理由在这一点上无法达到极限.
为什么堆栈跟踪包含比实际使用的帧少的帧?
Why do I get only 1024 elements in the stack trace,even though at least 10474 were used? Does it mean that not every call is in the stack trace?
看看getStackTrace()的文档:
Provides programmatic access to the stack trace information printed
by printStackTrace(). Returns an array of stack trace elements,each
representing one stack frame. The zeroth element of the array
(assuming the array’s length is non-zero) represents the top of the
stack,which is the last method invocation in the sequence. Typically,
this is the point at which this throwable was created and thrown. The
last element of the array (assuming the array’s length is non-zero)
represents the bottom of the stack,which is the first method
invocation in the sequence.Some virtual machines may,under some circumstances,omit one or more
stack frames from the stack trace. In the extreme case,a virtual
machine that has no stack trace information concerning this throwable
is permitted to return a zero-length array from this method. Generally
speaking,the array returned by this method will contain one element
for every frame that would be printed by printStackTrace. Writes to
the returned array do not affect future calls to this method.
在Peter Lawrey found the documentation的评论中,堆栈大小提到1024个默认限制:
07003
-XX:ThreadStackSize=512
Thread Stack Size (in Kbytes). (0 means use default stack size)
[Sparc: 512; Solaris x86: 320 (was 256 prior in 5.0 and earlier);
Sparc 64 bit: 1024; Linux amd64: 1024 (was 0 in 5.0 and earlier); all
others 0.]
可能还有其他因素也起作用.例如,这些问题提到另外两个选项:
> how to expand size of Java stack trace to see bottom of stack? (triggering a stack overflow)(-XXMaxJavaStackTraceDepth)
> How to avoid the 1024 lines of Java exception stack limit(-Xss)