2016-01-05 6 views
0

Я реализую внешний вид для большого файла (~ 30 ГБ), поэтому после того, как я написал фрагменты на диске, создаю chunks раз BufferedReader(new OutputStreamWriter(new FileOutputStream(outputPath), "UTF-8"), maxBufferSize), являющийся maxBufferSize = Runtime.getRuntime().freeMemory()/chunks. Однако я получаю исключение OutOfMemory.JVM из памяти

Я предполагаю, что сборщик мусора не успел очистить память (когда я останавливаюсь с отладчиком, он не генерирует исключение), но в этом случае почему Runtime.getRuntime().freeMemory() получил этот результат?

Можно ли явно вызвать сборку мусора, или единственный вариант - спящий процесс в течение некоторого времени?

+0

Возможный дубликат [Можно ли явно называть сборщик мусора?] (Http://stackoverflow.com/questions/15632734/can-we-call-the-garbage-collector-explicitly) –

+0

Обратите также внимание на то, что freeMemory() сообщает вам общую сумму свободного места в куче, но нет никакой гарантии, что существует один непрерывный блок, который большой (на самом деле, как правило, это не так). –

+0

Было бы важно знать, что вы получаете от OutOfMemoryError, не зная, что мы можем отправить вас в совершенно неправильном направлении. Также некоторый (релевантный) код был бы хорош .... –

ответ

2

Можно явно вызывать сборки мусора

Да, это возможно. Но это не принесет пользы.

JVM только выдает OOME после выполнения полного GC. Вызов System.gc() явно (скорее всего) будет просто потерять процессорное время.


На самом деле, я думаю, что ваша реальная проблема здесь:

создать chunks раз BufferedReader(new OutputStreamWriter(new FileOutputStream(outputPath), "UTF-8"), maxBufferSize) будучи maxBufferSize = Runtime.getRuntime().freeMemory()/chunks.

При рассмотрении различных накладных расходов объектов (maxBufferSize + overheads) * chunks, вероятно, немного больше, чем количество свободной памяти.

В общем, это плохая идея запускать кучу Java в полной мере. Даже если вы не исчерпаете пространство целиком, вы можете обнаружить, что работа, близкая к полной, вызовет множество (слишком много) сборщиков мусора.

В этом случае вы действительно не получаете много преимуществ от наличия действительно больших буферов ввода-вывода. Буферы в диапазоне от 8 КБ до 64 КБ должны быть в порядке ... это мое чувство кишки. См. Также комментарий Питера Лори!

+0

Буферы размером более 32 КБ могут быть немного медленнее. Я подозреваю, что это связано с размером кеша L1 cpu, но я обнаружил, что он меняется в зависимости от того, какой оптимальный размер. –

0

Вы можете использовать System.gc(), но это не самое полезное. Вы могли бы попробовать дать программе больше памяти.

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