OutofMemory Ошибка добавления LinkedList - PullRequest
1 голос
/ 04 марта 2011

Я пытаюсь прочитать текстовый файл (книгу), а затем добавить каждую строку в связанный список.Однако, когда я запускаю код, я получил ошибку вне памяти на l.add(line);.Не могли бы вы сказать мне, что я делаю не так с этим кодом?Или есть ли лучший способ хранить значения String вместо LinkedList?

Большое спасибо!

public Book (String bookname) throws java.io.IOException{
    f = new FileReader(bookname);
    b = new BufferedReader(f);
    l = new LinkedList<String>();
    String line = b.readLine();
    while (line != null) {
        l.add(line);
    }
    b.close();
}

Ответы [ 6 ]

6 голосов
/ 04 марта 2011

Как отмечают другие, вы создали бесконечный, потребляющий память цикл.Обычная идиома для чтения из BufferedReader такова:

String line;
while ( ( line = b.readLine() ) != null) {
    l.add(line);
}

Полагаю, вполне возможно, что содержание книги слишком велико, чтобы в любой момент поместиться в память.Вы можете увеличить объем памяти, доступной для JVM, используя аргумент Xmx, а именно:

java -Xmx1G MyClass

Значение по умолчанию для этого составляет 64 МБ, что не так много в наши дни.

2 голосов
/ 04 марта 2011

Возможно, вам следует заменить

while (line != null) {
    l.add(line);
}

на

while (line = b.readLine()) {
    l.add(line);
}
2 голосов
/ 04 марта 2011

Вы добавляете одну и ту же строку снова и снова, пока не закончится память:

String line = b.readLine();
while (line != null) {
    l.add(line);
}

Видите?Переменная line читается вне цикла и никогда не изменяется внутри цикла.

1 голос
/ 04 марта 2011

Хотя цикл никогда не завершается, потому что переменная line никогда не равна нулю.Попробуйте это:

String line = "";
while ((line = b.readLine())!= null)
{
   l.add(line);
}
b.close();
0 голосов
/ 04 марта 2011

Я согласен с mjg123. И будьте осторожны с ожиданием незапамятных времен. и я прошу вас взглянуть на этот блог для получения более подробной информации о том, как справиться с такими ситуациями Нажмите здесь

0 голосов
/ 04 марта 2011

Проще говоря, объем памяти, необходимый для хранения строк (и всего остального в вашей программе), превысил общий объем свободной памяти, доступной в куче.

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

Если вы не увеличили пространство кучи Java-приложения, оно может работать с довольно низкими значениями по умолчанию. В этом случае вам следует рассмотреть возможность предоставления следующего аргумента командной строки для вызова java:

-Xmx512m

(где 512m подразумевает 512 мегабайт пространства кучи; вы можете использовать, например, -Xmx2g или все, что вы считаете подходящим.)

С другой стороны, если вы уже работаете с большой кучей (намного больше, чем общий размер строк, которые вы хотите сохранить в памяти), это может указывать на проблему с памятью где-то еще. Сколько персонажей в книге? Для хранения всех строк потребуется по крайней мере в два раза больше байтов, и, вероятно, на 20% или более, чтобы учесть накладные расходы. Если ваши расчеты показывают, что ваше текущее пространство кучи должно содержать все эти данные, в других местах могут возникнуть проблемы. В противном случае вы теперь знаете, что вам нужно для увеличения кучи как минимум.

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

...