简体   繁体   中英

“Requested array size exceeds VM limit” at java.io.PrintWriter.newLine

I'm getting the following very strange error from my server application (running 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)

Looking at PrintWriter.java:480:

out.write(lineSeparator);

lineSeperator is set in the constructor of PrintWriter, as follows:

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

I've rerun my application twice on this particular data set, and I get the same exception at the exact same place twice. It seems very unlikely to me that it would be the append of the new line seperator (which should be just "\\n") that would cause the OOM.

The printStackTrace function in the trace above is called from:

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

Has anyone seen anything similar, or know if the lineSeperator could somehow get really long?

Has anyone seen anything similar, or know if the lineSeperator could somehow get really long?

This code is just retrieving system properties requires permissions which the calling code may not have. (See here )

It can be set via :

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

But as for me, there is no reason to set it such long.

Maybe you investigate at the wrong place. The reason of the OOM is located at this point java.util.Arrays.copyOf(Arrays.java:2367) . Seems the remaining free memory is lower then the array which should be copied in size.

What is the Throwable which should be printed? Maybe there is some circular or recursive exception handling involved somewhere in the code.

This is same questions posted here: https://stackoverflow.com/posts/35143048

try

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

It creates a PrintWriter instance which flushes content everytime when there is a new line or format.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM