Android - OutOfMemory при чтении текстового файла - PullRequest
4 голосов
/ 20 июня 2011

Я делаю приложение для словаря на Android.Во время запуска приложение загрузит содержимое файла .index (~ 2 МБ, 100 000+ строк)

Однако, когда я использую BufferedReader.readLine () и что-то сделаю с возвращенной строкой, приложение вызовет OutOfMemory.

// Read file snippet
Set<String> indexes = new HashSet<String)();

FileInputStream is = new FileInputStream(indexPath);
BufferedReader reader = new BufferedReader(new InputStreamReader(is));

String readLine;

while ( (readLine = reader.readLine()) != null) {
    indexes.add(extractHeadWord(readLine));
}

// And the extractHeadWord method
private String extractHeadWord(String string) {
    String[] splitted = string.split("\\t");
    return splitted[0];
}

При чтении журнала я обнаружил, что во время выполнения GC вызывает явную очистку объектов много раз (GC_EXPLICIT освобождает объекты xxx, в которых xxx - большое число, такое как 15000, 20000).

И я попробовал другой способ:

final int BUFFER = 50;
char[] readChar = new char[BUFFER];

//.. construct BufferedReader

while (reader.read(readChar) != -1) {
    indexes.add(new String(readChar));
    readChar = new char[BUFFER];
}

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

Есть ли какое-либо решение, которое быстро работает как второй фрагмент и легко используется как первый?

С уважением.

Ответы [ 2 ]

4 голосов
/ 20 июня 2011

extractHeadWord использует метод String.split. Этот метод не создает новые строки, но опирается на базовую строку (в вашем случае объект line) и использует индексы для указания «новой» строки.

Поскольку вас не интересует остальная часть строки, вам нужно выбросить ее, чтобы она собирала мусор, иначе вся строка будет в памяти (но вы используете только ее часть).

Вызов конструктора String(String) («конструктор копирования») отбрасывает остаток строки:

private String extractHeadWord(String string) {
    String[] splitted = string.split("\\t");
    return new String(splitted[0]);
}
3 голосов
/ 20 июня 2011

Что произойдет, если ваш extractHeadWord сделает это return new String(splitted[0]);.

Это не приведет к сокращению временных объектов, но может уменьшить площадь приложения. Я не знаю, делает ли split примерно то же самое, что и подстрока, но я думаю, что это так. подстрока создает новый вид исходных данных, что означает, что полный массив символов будет храниться в памяти. Явный вызов new String(string) усекает данные.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...