2016-11-28 5 views
0

У меня проблема с кучей Java Java BlueJ. Я написал программу, которая читает в .txt строку String и проходит через все символы строки и делает некоторые вещи (думаю, это не очень важно). Некоторые из .txt действительно большие (около 200 миллионов). Если я пытаюсь выполнить программу с помощью этих .txt, я получаю этот код ошибки «Исключение в потоке» AWT-EventQueue-0 «java.lang.OutOfMemoryError: Java heap space». Я увеличил bluej.windows.vm.args и bluej.windows.vm.args в bluej.def до 8gb. И это все еще не работает. Но я на самом деле догадываюсь, что даже 200-миллионная строка String не будет превышать этот предел. Вот мой код, как я прочитал в .txtJava куча пространства BlueJ

try 
    { 
     FileReader reader = new FileReader(input.getText()); 
     BufferedReader bReader = new BufferedReader(reader); 
     String parcour = ""; 
     String line = bReader.readLine(); 
     while(line != null) 
     { 
      parcour += line; 
      line = bReader.readLine();    
     } 

input.getText() получает пути к файлам. Я был бы очень благодарен за ответ. Спасибо :) - Cyaena

+1

Вы сохраняете весь файл в переменной 'parcour'. Это будет много памяти. Кроме того, рассмотрите возможность использования 'StringBuilder' при добавлении данных в строку – ar34z

+0

. Но на самом деле строка не должна есть столько памяти, не так ли? Какое преимущество я должен использовать StringBuilder? И как мне настроить его примерно? – Cyaena

+1

Я не тот человек, который объясняет использование памяти, но хранит 200 мил. символы в памяти не звучат очень многообещающе. При конкатенации строк в цикле 'StringBuilder' работает быстрее. Что вы пытаетесь сделать с 200 миллионами строк? Возможно, это может помочь вам: http://stackoverflow.com/questions/10202905/is-it-advisable-to-store-large-strings-in-memory-or-repeatedly-read-a-file Дополнительная информация об использовании памяти : http://www.javamex.com/tutorials/memory/string_memory_usage.shtml – ar34z

ответ

0

В нижеследующем пояснении только объемная память для данных находится в области. Вся дополнительная потребность в памяти для структур не учитывается. Это более общий обзор в виде глубоких деталей.

память съедается на этих линиях

String parcour = ""; 
... 
String line = bReader.readLine(); 
... 
parcour += line; 

Линия parcour += line компилируется в файл класса, как

new StringBuilder().append(parcour).append(line).toString() 

Предположим parcour содержит строку размером 10 МБ и line бы размера 2 МБ. Затем память, выделенная во время parcour += line; будет (примерно)

// creates a StringBuilder object of size 12 MB 
new StringBuilder().append(parcour).append(line) 

// the `.toString()` would generate a String object of size 12 MB 
new StringBuilder().append(parcour).append(line).toString() 

Ваш код должен перед вновь созданной строки присваивается parcour около 34 МБ.

parcour       = 10 MB 
the temporary StringBuilder object = 12 MB 
the String fromStringBuilder  = 12 MB 
------------------------------------------ 
total        34 MB 

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

OOMString.java

class OOMString { 
    public static void main(String[] args) throws Exception { 
     String parcour = ""; 
     char[] chars = new char[1_000]; 
     String line = new String(chars); 
     while(line != null) 
     { 
      System.out.println("length = " + parcour.length()); 
      parcour += line; 
     }   
    } 
} 

OOMStringBuilder.java

class OOMStringBuilder { 
    public static void main(String[] args) throws Exception { 
     StringBuilder parcour = new StringBuilder(); 
     char[] chars = new char[1_000]; 
     String line = new String(chars); 
     while(line != null) 
     { 
      System.out.println("length = " + parcour.length()); 
      parcour.append(line); 
     }   
    } 
} 

Оба сниппеты сделать то же самое. Они добавляют строку 1000 символов к parcour до тех пор, пока не будет сброшена OutOfMemoryException. Чтобы ускорить его, мы ограничиваем размер кучи до 10 МБ.

выход java -Xmx10m OOMString

length = 1048000 
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space 

выход java -Xmx10m OOMStringBuilder

length = 2052000 
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space 

При выполнении кода вы заметите, что OOMString потребности гораздо больше времени на провал (даже при более короткой длине), чем OOMStringBuilder.

Вам также необходимо иметь в виду, что один символ имеет длину два байта.Если ваш файл содержит 100 символов ASCII, они потребляют 200 байт в памяти.

Возможно, эта небольшая демонстрация может объяснить это немного для вас.

0

У меня были проблемы с ошибками BlueJ и Heap Space. В моем случае открытие терминала разбило все приложение. Я подозреваю, что это как-то связано с генерированием большого количества выходных данных, подобно вашей большой строке. В моем случае я случайно создал бесконечный цикл, который разбил окно терминала.

Мне пришлось удалить все файлы свойств. Теперь BlueJ снова работает и не дает больше OutOfMemoryErrors. Я надеюсь, что это может быть полезно и в других случаях.