Я не могу обработать 5 ГБ текстовый файл при получении этой ошибки?

1

Я использую StringBuilder, читая каждый твит файл и записывая его после фильтрации его в другой файл. Я также смываю свой StringBuilder в конце каждого цикла. Я нахожусь в сетчатой сетчатке 20 ГБ оперативной памяти в середине 2012 года.

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
    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:535)
    at java.lang.StringBuffer.append(StringBuffer.java:322)
    at java.io.BufferedReader.readLine(BufferedReader.java:363)
    at java.io.BufferedReader.readLine(BufferedReader.java:382)
    at Parser.main(Parser.java:52)
  • 2
    Разместите свой код. Это действительно не похоже, что вы очищаете свой StringBuffer . Для 5 ГБ вам может понадобиться временно, может быть, в три раза больше: размер буфера почти 5 ГБ можно изменить до 10 ГБ, поэтому он составляет 15 ГБ (при условии, что коэффициент роста равен 2).
  • 0
    Проверьте этот поток, чтобы выделить больше памяти stackoverflow.com/questions/2610194/…
Показать ещё 5 комментариев
Теги:

2 ответа

0
Лучший ответ

Из структуры программы мы можем заключить, что hog-память - это либо объект, который увеличивается на каждой итерации цикла (случай 1), либо объект, который становится большим в течение одной итерации (случай 2).

Столбец указывает на неудачное выделение памяти, когда BufferedReader попытался изменить размер своего внутреннего буфера символов, чтобы разместить строку ввода. Как долго эта линия во время неудачи? Вы можете узнать, запустив свою программу в отладчике с контрольной точкой исключения в OutOfMemoryError и проверив переменную, содержащую размер массива, который не может быть выделен. Если он не огромен, мы можем исключить случай 2.

Наиболее вероятным подозреваемым для случая 1 является LinkedHashSet, сохраняющий tweet_f для всех твитов на выходе. Попробуйте оценить его размер (приблизительную оценку можно получить с помощью ln.size() * (средняя длина строки 50 + 2 * в символах) и убедитесь, что у вас достаточно памяти для ее хранения.

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

  • 0
    1. Есть ли VisualVM для Mac? 2. Я не храню все твиты в LinkedHashMap, он хранит только те твиты, которые соответствуют фильтру, как вы можете видеть, он выполняет .add (бла) внутри цикла if. Не говоря уже об этом фрагменте кода, я запускаю стандартный пример приложения BufferedFile Reader Hello World, читая тот же файл и распечатывая строки. Даже это не удается.
  • 0
    1. Будучи частью Oracle JDK, я ожидаю, что JVisualVM будет доступен и на Mac. 2. Следовали ли вы моему предложению, чтобы проверить, что длины линий разумны?
1

Похоже, у вас утечка памяти. Трудно дать вам конкретный совет по коду без исходного кода, но, возможно, у вас есть что-то, ссылающееся на ваш StringBuilder даже после его покраснения? VisualVM - это хороший бесплатный инструмент, который может использоваться для отслеживания, где такая проблема возникает во время выполнения. В этом блоге рассказывается, как это сделать: http://rejeev.blogspot.com/2009/04/analyzing-memory-leak-in-java.html

  • 0
    Я попытался выделить 20G, используя -Xmx20g, но все еще говорит Исключение в потоке "main" java.lang.OutOfMemoryError: Размер запрашиваемого массива превышает ограничение виртуальной машины

Ещё вопросы

Сообщество Overcoder
Наверх
Меню