Java 尝试打印stacktrace时出现StackOverflower错误

Java 尝试打印stacktrace时出现StackOverflower错误,java,stack-trace,stack-overflow,Java,Stack Trace,Stack Overflow,在尝试将stacktrace打印到控制台时,我得到了以下stacktrace: java.lang.StackOverflowError at java.io.FileOutputStream.writeBytes(Native Method) at java.io.FileOutputStream.write(Unknown Source) at java.io.BufferedOutputStream.flushBuffer(Unknown Source) at java.io.Buffer

在尝试将stacktrace打印到控制台时,我得到了以下stacktrace:

java.lang.StackOverflowError
at java.io.FileOutputStream.writeBytes(Native Method)
at java.io.FileOutputStream.write(Unknown Source)
at java.io.BufferedOutputStream.flushBuffer(Unknown Source)
at java.io.BufferedOutputStream.write(Unknown Source)
at java.io.PrintStream.write(Unknown Source)
at sun.nio.cs.StreamEncoder.writeBytes(Unknown Source)
at sun.nio.cs.StreamEncoder.implFlushBuffer(Unknown Source)
at sun.nio.cs.StreamEncoder.flushBuffer(Unknown Source)
at java.io.OutputStreamWriter.flushBuffer(Unknown Source)
at java.io.PrintStream.write(Unknown Source)
at java.io.PrintStream.print(Unknown Source)
at java.io.PrintStream.println(Unknown Source)
at java.lang.Throwable.printStackTrace(Throwable.java:461)
at java.lang.Throwable.printStackTrace(Throwable.java:451)
...
以前有人见过这样的东西吗?这是什么原因造成的?(不幸的是,我从一个用户那里收到了stacktrace,所以我不能说JVM配置是否有任何改变。)

导致这种情况的方法调用是一个简单的捕获和打印,如下所示:

try {
  ...
  File canFile = new File(path).getCanonicalFile();
  ...
} catch (IOException e) {
  e.printStackTrace();
}

虽然我不能发布更多的代码,但我可以保证IOException是由getCanonicalFile调用引发的,因为这是try子句中唯一可以引发IOException的调用。

如果您初始化两个
Throwable
是彼此的共同原因,如果您试图打印其中一个的stacktrace,将得到一个
StackOverflowerError

下面的类演示了这种行为:

public class StackTraceStackOverflow {
    public static void main(String[] args) {
        Error e = new Error();
        Error f = new Error(e);
        e.initCause(f);
        e.printStackTrace();
    }
}
在本例中,我们需要两个
Throwable
s,因为无法将
Throwable
设置为其自身原因。如果您尝试执行此操作,将得到一个
IllegalArgumentException

或者,如果您有一个长得离谱的原因链异常,您也可以得到堆栈溢出错误。至少在我的机器上(Kubuntu Natty,x64,OpenJDK 1.6),我发现8000个原因异常链足以生成
StackOverflowerError
,如下类所示:

public class StackTraceStackOverflow2 {
    public static void main(String[] args) {
        Error e = null;
        for (int i = 0; i < 8000; ++i) {
            e = new Error(null, e);
        }

        e.printStackTrace(System.out);
    }
}
公共类StackTraceStackOverflow2{
公共静态void main(字符串[]args){
错误e=null;
对于(int i=0;i<8000;++i){
e=新错误(空,e);
}
e、 printStackTrace(系统输出);
}
}
您可能需要调整其他系统上的数字8000


注意,在第二个示例中,我使用了两个参数
Error
构造函数。如果我使用的构造函数只接受一个
Throwable
参数,则会使用原因异常填充异常消息。随着异常链的增长,此消息变得越来越长,因此,与StackOverflower上的Java文档为1行相比,您更可能最终出现
OutOfMemoryError
而不是
StackOverflowerError,因此我打赌一定是无限递归造成的。“由于应用程序递归太深而发生堆栈溢出时引发。”
e.printStackTrace()不是原因。
try
block中有什么?@gurung:
e.printStackTrace()
很可能是原因。看我的答案。@gurung:看我更新的帖子。e、 调用printStackTrace()是因为它捕获了从文件.getCanonicalFile()引发的IOException。然而,我确实认为e.printStackTrace()导致了StackFverFlower错误,因为stacktrace就是这么说的。@pythondude
StackOverflowerError
不是
IOException
的超类,它们之间没有任何关系。您的
StackOverflowerError
异常是从其他地方抛出的!我需要一些时间来验证这一点。谢谢你的建议。