Я получаю следующее сообщение об ошибке очень странно из моего приложения сервера (под управлением Java 7):«Запрашиваемый размер массива превышает предел VM» на java.io.PrintWriter.newLine
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
может каким-то образом получить очень долго?
Ну, я знаю, что это называется «разделитель строк», а не «разделитель строк». Будет ли это источником вашей ошибки? – Kayaman
Измените его на lineSeparator = System.getProperty ("line.separator"); – Maksym
Глядя на stacktrace, кажется, вы пытаетесь помещать слишком много данных в 'StringBuilder', используемый внутри' StringWriter', который вы передаете 'PrintWriter'. Тот факт, что разделитель файлов является именно тем символом, который запускает переполнение, вероятно, является чистым совпадением. –