16

在 Java 中,有没有办法查看完整的、未截断的堆栈跟踪(例如,通过增加记录的帧数),或者以其他方式到达堆栈跟踪的底部?通常堆栈跟踪在 1024 帧处从顶部截断,但对于堆栈溢出问题,这是毫无价值的,因为您确实需要查看是谁发出了触发递归的调用,在底部附近。在堆栈中间截断会更好,但显然 Sun 的 JVM 不够聪明,无法做到这一点。

也许甚至是一些特殊的太阳特定标志?我尝试将堆栈大小减小到允许的最小值(-Xss1000),但这仍然超过 1024 帧的价值。

就我而言,我正在尝试调试 Hadoop 映射器中发生的堆栈溢出,但前提是在非常大的输入上运行时。我认为问题出现是因为递归操作(Scala's foldRight)正在一个非常非常大的链表上完成,我需要以非递归方式重写它......但我需要知道是谁调用了foldRight. 这是一个在很多地方直接和间接调用的基本例程,并且我正在使用大量代码,所以这是非常不明显的。

4

4 回答 4

25

尝试-XX:MaxJavaStackTraceDepthJVM 选项。

这是来自Stas 博客的描述

最大限度。不。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 进行测试)。

于 2012-08-08T20:03:54.800 回答
2

您可以自己迭代堆栈跟踪

Throwable t =

for(StackTraceElement ste: t.getStackTrace()) {
    // is it a repeat??

}

默认的 printStackTrace 将打印已记录的每个级别。您的问题是堆栈对于它放入堆栈跟踪的内容来说太深了。

你能尝试减少你的筹码量吗?

于 2012-08-08T13:17:36.537 回答
-1

如果您在调用进入可疑的堆栈溢出之前可以访问它,则可以生成一个额外的堆栈跟踪,例如new Exception().getStackTrace. 请注意,foldRight它本身不会产生无限递归。也许您只是内存不足,请尝试增加 JVM 的堆栈大小。

于 2012-08-08T13:17:52.233 回答