OutOfMemoryError при присоединении к списку строк в Java - PullRequest
0 голосов
/ 09 октября 2018

Итак.Я пробовал:

StringBuilder sb = new StringBuilder();
for(String bufferItem: buffer){
    sb.append(bufferItem);
}

, а также пробовал:

String.join("\n", buffer)

Я объединяю большие файлы (до 10 ГБ) в памяти в системе с более чем 100 ГБ.Ниже приведена трассировка стека.Как я могу решить эту проблему?

Exception in thread "main" java.lang.OutOfMemoryError
    at java.lang.AbstractStringBuilder.hugeCapacity(AbstractStringBuilder.java:161)
    at java.lang.AbstractStringBuilder.newCapacity(AbstractStringBuilder.java:155)
    at java.lang.AbstractStringBuilder.ensureCapacityInternal(AbstractStringBuilder.java:125)
    at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:448)
    at java.lang.StringBuilder.append(StringBuilder.java:136)
    at java.lang.StringBuilder.append(StringBuilder.java:76)
    at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:484)
    at java.lang.StringBuilder.append(StringBuilder.java:166)
    at java.util.StringJoiner.add(StringJoiner.java:185)
    at java.lang.String.join(String.java:2504)

Ответы [ 2 ]

0 голосов
/ 09 октября 2018

Вы не можете создавать строки с таким количеством символов.OutOfMemoryError не потому, что куча была заполнена, а потому, что вы пытаетесь построить строку больше максимально возможного размера.

Максимально возможный размер определяется как 2 для степени 31, минус 1, минус 8. Это примерно 2 Гб, если вы используете только однобайтовые символы в файле.См. Источник AbstractStringBuilder.

/**
 * The maximum size of array to allocate (unless necessary).
 * Some VMs reserve some header words in an array.
 * Attempts to allocate larger arrays may result in
 * OutOfMemoryError: Requested array size exceeds VM limit
 */
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

Вы просто не можете создавать строки больше этого.

Почему вы хотите объединять файлы в памяти, когда вы можете присоединиться к ним во время их потоковой передачина диск?

0 голосов
/ 09 октября 2018

Прежде всего, вероятно, не рекомендуется использовать такой объем памяти, и я бы разбил его на куски разумного размера (возможно, объединить 100 строк за раз, а затем записать в файл).Если вам действительно нужно использовать столько памяти, вам нужно будет передать -Xmx10G в JVM.Это выделяет больше пространства кучи для использования Java.

...