java.io.PrintWriter.newLine中“请求的数组大小超过VM限制”

时间:2015-04-21 12:36:04

标签: java out-of-memory printwriter

我从服务器应用程序(运行Java 7)中收到以下非常奇怪的错误:

Caused by: java.lang.OutOfMemoryError: Requested array size exceeds VM limit
    at java.util.Arrays.copyOf(Arrays.java:2367)
    at java.lang.AbstractStringBuilder.expandCapacity(AbstractStringBuilder.java:130)
    at java.lang.AbstractStringBuilder.ensureCapacityInternal(AbstractStringBuilder.java:114)
    at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:415)
    at java.lang.StringBuffer.append(StringBuffer.java:237)
    at java.io.StringWriter.write(StringWriter.java:101)
    at java.io.PrintWriter.newLine(PrintWriter.java:480)
    at java.io.PrintWriter.println(PrintWriter.java:629)
    at java.io.PrintWriter.println(PrintWriter.java:757)
    at java.lang.Throwable$WrappedPrintWriter.println(Throwable.java:764)
    at java.lang.Throwable.printStackTrace(Throwable.java:655)
    at java.lang.Throwable.printStackTrace(Throwable.java:721)

看看PrintWriter.java:480:

out.write(lineSeparator);

lineSeperator在PrintWriter的构造函数中设置,如下所示:

lineSeparator = java.security.AccessController.doPrivileged(new sun.security.action.GetPropertyAction("line.seperator"));

我已经在这个特定的数据集上重新运行了我的应用程序两次,并且在完全相同的位置两次得到相同的异常。对我来说似乎不太可能是新行分隔符(应该只是“\ n”)的附加物会导致OOM。

上面跟踪中的printStackTrace函数来自:

public static String getMessage(Throwable t) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
t.printStackTrace(pw); // THIS LINE <-----
return sw.toString();
}

有没有人见过类似的东西,或者知道lineSeperator是否会以某种方式变得非常长?

3 个答案:

答案 0 :(得分:0)

  

有没有人见过类似的东西,或者知道lineSeperator是否会以某种方式变得非常长?

此代码只是检索系统属性需要调用代码可能没有的权限。 (见here

可以通过以下方式设置:

System.setProperty("line.separator", whatever)

但就我而言,没有理由设定这么久。

答案 1 :(得分:0)

也许你在错误的地方进行调查。 OOM的原因位于此java.util.Arrays.copyOf(Arrays.java:2367)。似乎剩余的可用内存低于应该以大小复制的数组。

应该打印的Throwable是什么?也许在代码中的某处涉及一些循环或递归异常处理。

答案 2 :(得分:0)

这是同样的问题: https://stackoverflow.com/posts/35143048

boolean autoFlush = true; PrintWriter output = new PrintWriter(myFileName, autoFlush);

它创建一个PrintWriter实例,每当有新的行或格式时,它就会刷新内容。