Утечка памяти при чтении файла в Java

#java #json #garbage-collection #fileinputstream

#java #json #сбор мусора #fileinputstream

Вопрос:

У меня есть файл JSON размером 54 120 байт, который находится в одной строке

Я пытаюсь прочитать это в строку в приложении для Android, используя:

 //Method from class FileManager
public String readInternalFile(String filename) throws IOException {
        Log.d(getClass().getName(),"Reading Internal File: "   filename);

        // Open file
        FileInputStream fIS = context.openFileInput(filename);
        Log.d(getClass().getName(),"File is "   fIS.available()   " bytes");

        // Process file
        String s = "";
        int ch;
        while ((ch = fIS.read()) != -1) {
            s  = (char) ch;
        }

        //Close InputStream
        if(fIS!= null){
            fIS.close();
        }
        Log.d(getClass().getName(),"File is "   s.length()   " characters long");
        return s;
}
  

Когда я запускаю это в своем тестовом приложении JUnit или в эмуляторе, я получаю стену текста журнала для сборщика мусора:

Данные журнала

Кажется, это никогда не заканчивается и замедляет работу моего приложения. Есть ли способ, которым я могу прочитать это, который не приведет к этому?

Если это поможет, доступ к файлу JSON можно получить здесь. Это просто новостная лента.

Комментарии:

1. Я думаю, проблема в том, как вы создаете свой String … Не используйте конкатенацию. Используйте StringBuilder .

2. Возможно, это не связано, но должны быть лучшие способы чтения файла, чем выполнение его по одному символу за раз.

3. Вам следует использовать = со строкой. Вместо этого используйте StringBuffer и вызывайте append для добавления каждого символа. Также оберните ваш входной поток в BufferedInputStream

4. @JoachimPileborg Мои мысли точно, я буду исследовать StringBuilder

5. Это не похоже на утечку памяти, вместо этого сборщик мусора выполнял частую сборку мусора. Причиной этого стало чтение строки char по char. Для каждого прочитанного символа java преобразует символ в строку (так что это один новый объект), затем вы объединяете и присваиваете его s другому новому объекту. Итак, это как минимум 108240 новых объектов для вашего 54120 байтового файла, которые имеют очень короткий жизненный цикл, прежде чем сборщик мусора попытается их очистить.

Ответ №1:

Решением этой проблемы было отформатировать JSON файл перед его чтением в стиле «pretty print» с новыми строками и отступами, а затем использовать BufferedReader с readLine()