2015-04-21 2 views
1

Я получаю следующее сообщение об ошибке очень странно из моего приложения сервера (под управлением 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 может каким-то образом получить очень долго?

+0

Ну, я знаю, что это называется «разделитель строк», а не «разделитель строк». Будет ли это источником вашей ошибки? – Kayaman

+0

Измените его на lineSeparator = System.getProperty ("line.separator"); – Maksym

+0

Глядя на stacktrace, кажется, вы пытаетесь помещать слишком много данных в 'StringBuilder', используемый внутри' StringWriter', который вы передаете 'PrintWriter'. Тот факт, что разделитель файлов является именно тем символом, который запускает переполнение, вероятно, является чистым совпадением. –

ответ

0

Кто-нибудь видел что-либо подобное или знает, может ли линияSeperator как-то получить очень долго?

Этот код только для получения свойств системы требует разрешений, которые могут иметь код вызова. (См here)

Он может быть установлен с помощью:

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

Но для меня, нет никаких причин, чтобы установить это такие длинные.

0

Возможно, вы исследуете не то место. Причина OOM находится в этом пункте java.util.Arrays.copyOf(Arrays.java:2367). Кажется, оставшаяся свободная память ниже, чем массив, который нужно скопировать в размере.

Что такое Throwable, который должен быть напечатан? Возможно, в коде есть какая-то циклическая или рекурсивная обработка исключений.

0

Это те же вопросы, размещенные здесь: https://stackoverflow.com/posts/35143048

попробовать

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

Это создает PrintWriter экземпляр, который промывает каждый раз, когда содержимое появляется новая строка или формат.

Смежные вопросы