Ошибка пространства кучи Java при чтении больших файлов

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

private   String processFile(FileItemStream item) throws IOException{

        InputStream is=null;

        try{
            is=item.openStream();
            return IOUtils.toString(is, "UTF-8");
        }
        finally {

            IOUtils.closeQuietly(is);

        }

    }




data=processFile(item)//method call
SomeClass(data);//passing the data string to this class

person Gowrav    schedule 01.07.2013    source источник


Ответы (3)


Вы должны передать свой is в класс, которому нужны данные. Пока вы не прочитаете все содержимое is сразу, вы не израсходуете всю свою память. Измените свой код на это:

InputStream is = null;
try {
    is = getFileAsStream(item);
    SomeClass(is)  //of course this probably doesn't compile, I'm just using your code sample
} finally {
    //close is
}
person Daniel Kaplan    schedule 01.07.2013
comment
но другой класс получает только строку в качестве параметра. Класс hter на самом деле является предварительно написанным классом IBM, я принимаю только строку в качестве параметра - person Gowrav; 01.07.2013
comment
@user2535809 user2535809, измените его, чтобы он принимал InputStream в качестве параметра. Вы можете это сделать? - person Daniel Kaplan; 01.07.2013
comment
Нет. Это класс, в котором я говорю о com.ibm.cognos.manyeyes.container.VisualizationRenderer;. Есть ли способ сделать это, не загружая весь файл в основную память? - person Gowrav; 01.07.2013
comment
@ user2535809 Я не знаю, что это такое. Ссылку на документацию, пожалуйста. - person Daniel Kaplan; 01.07.2013

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

Если API не позволяет вам сделать что-либо из вышеперечисленного, то единственное, что вы можете сделать, это увеличить объем памяти, который может использовать Java. Для этого запустите Java с ключом -Xmx512m, где 512 — это объем памяти, который вы можете выделить для Java.

person Sarel Botha    schedule 01.07.2013

Если вы действительно не можете изменить API, который вы вызываете, чтобы получить что-то помимо строки, вам нужно будет обойти проблему, предоставив вашей JVM больше памяти. Это можно изменить, отправив параметр в JVM.

-Xmx<size>

Например, вы можете использовать такой параметр, чтобы дать JVM максимальную кучу 2 ГБ.

-Xmx2g

Хотя, если вы используете API, который принимает строку в качестве параметра и пытается передать строку размером в несколько гигабайт, вы почти наверняка неправильно используете их API. Если кто-то создаст API, который ожидает большие объемы данных, он не будет создавать его с одной строкой в ​​качестве параметра. Удачи.

person jjathman    schedule 01.07.2013