在Java中,有没有办法查看完整的,未截断的堆栈跟踪(例如,通过增加记录的帧数),或以其他方式获取堆栈跟踪的 bottom ?通常情况下,堆栈跟踪在1024帧的情况下从顶部被截断,但是对于堆栈溢出问题,这实际上是毫无价值的,因为您确实需要查看是谁进行了触发递归的调用,靠近底部。更好的是在堆栈的中间中截断,但显然Sun的JVM不够聪明,无法做到这一点。
甚至可能还有一些特殊的Sun特定标志?我尝试将堆栈大小减小到允许的最小值(-Xss1000),但仍然超过1024帧。
就我而言,我正在尝试调试Hadoop映射器中发生的堆栈溢出,但仅限于在非常大的输入上运行时。我假设问题来了,因为递归操作(Scala的foldRight
)正在一个非常非常大的链表上完成,我需要非递归地重写它...但我需要知道是谁打了电话到foldRight
。这是一个直接和间接在很多地方调用的基本例程,我正在使用很多很多代码,所以这非常不明显。
答案 0 :(得分:20)
尝试-XX:MaxJavaStackTraceDepth
JVM选项。
以下是Stas's Blog
的说明最大。没有。 Java异常的堆栈跟踪中的行(0表示全部)。 使用Java> 1.6,值0实际上意味着0.值-1或必须指定任何负数来打印所有堆栈(在Windows上使用1.6.0_22,1.7.0进行测试)。 使用Java< = 1.5,值0表示所有内容,JVM在负数上阻塞(在Windows上使用1.5.0_22进行测试)。
答案 1 :(得分:2)
尝试使用jstack:
http://docs.oracle.com/javase/6/docs/technotes/tools/share/jstack.html
http://docs.oracle.com/javase/7/docs/webnotes/tsg/TSG-VM/html/tooldescr.html#gblfh
答案 2 :(得分:1)
您可以自己迭代堆栈跟踪
Throwable t =
for(StackTraceElement ste: t.getStackTrace()) {
// is it a repeat??
}
默认的printStackTrace将打印已记录的每个级别。您的问题是堆栈太深,无法放入堆栈跟踪中。
你能尝试减少堆栈大小吗?
答案 3 :(得分:-1)
如果您在之前有权访问,那么它会进入可疑的堆栈溢出,您可以生成一个额外的堆栈跟踪,如new Exception().getStackTrace
。请注意,foldRight
本身不会产生无限递归。也许你只是耗尽了内存,试着增加JVM的堆栈大小。