我正在运行由另一个人编写的Java程序,该程序所处理的数据量超出了最初为该程序设计的数据。输入文件长10倍,运行时间大致为二次。我遇到了不同的问题,现在打算一点一点地解决它们,并感谢我能得到的所有帮助-非常感谢您的建议!
在执行过程中,已经打印了很多输出(重定向到文件)时,我得到以下输出:
Exception in thread "main" java.lang.StackOverflowError
at java.io.PrintStream.write(PrintStream.java:480)
[...]
at java.io.PrintStream.write(PrintStream.java:480)
堆栈跟踪是使我困惑的第一件事,因为它是一次又一次重复同一行的长时间重复。此外,它也不打算在代码或执行中的哪里出现问题。
我的想法/研究
PrintStream
仅搜索“ PrintStream”后的代码片段
// reset output stream to suppress the annoying output of the Apache batik library. Gets reset after lib call.
OutputStream tmp=System.out;
System.setOut(new PrintStream(new org.apache.commons.io.output.NullOutputStream()));
drawRes.g2d.stream(new FileWriter(svgFilePath), false);
System.setOut(new PrintStream(tmp));
寻求建议
如果您对下一步工作有什么建议,或者Java代码专门做什么,请帮助我理解它。尤其是堆栈跟踪使我感到沮丧,因为它没有提供开始修复的位置。对于如何解决此问题,获取堆栈跟踪信息,修复代码以避免StackOverflow等的通用方法,我也表示感谢。
一些系统环境事实
Java
openjdk version "1.8.0_121"
OpenJDK Runtime Environment (IcedTea 3.3.0) (suse-28.1-x86_64)
OpenJDK 64-Bit Server VM (build 25.121-b13, mixed mode)
请询问您是否需要更多信息!
注释
感谢您的答复!
答案 0 :(得分:7)
这两行看起来很可疑:
OutputStream tmp=System.out;
//...
System.setOut(new PrintStream(tmp));
System.out
已经是PrintStream
,所以恕我直言,这些行应显示为
PrintStream tmp=System.out;
//...
System.setOut(tmp);
否则将发生PrintStream
内PrintStream
s几乎无休止的包裹。 PrintStream的嵌套仅受Java堆空间限制-但调用级别的嵌套要低得多。
为验证该假设,我创建了一个小型测试程序,该程序首先包装System.out
20次,并打印堆栈跟踪以验证调用链。之后,它包装System.out
10_000次,并产生StackOverflowException。
import java.io.OutputStream;
import java.io.PrintStream;
public class CheckPrintStream {
public static void main(String[] args) {
PrintStream originalSystemOut = System.out;
System.setOut(new PrintStream(System.out) {
@Override
public void write(byte buf[], int off, int len) {
originalSystemOut.write(buf, off, len);
if (len > 2) {
new RuntimeException("Testing PrintStream nesting").printStackTrace(originalSystemOut);
}
}
});
for (int i = 0; i < 20; i++) {
wrapSystemOut();
}
System.out.println("Hello World!");
for (int i = 20; i < 10_000; i++) {
wrapSystemOut();
}
System.out.println("crash!");
}
private static void wrapSystemOut() {
OutputStream tmp = System.out;
System.setOut(new PrintStream(System.out));
}
}
大约6000到7000个PrintWriters的嵌套足以产生堆栈溢出。