В нижеследующем пояснении только объемная память для данных находится в области. Вся дополнительная потребность в памяти для структур не учитывается. Это более общий обзор в виде глубоких деталей.
память съедается на этих линиях
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 байт в памяти.
Возможно, эта небольшая демонстрация может объяснить это немного для вас.
Вы сохраняете весь файл в переменной 'parcour'. Это будет много памяти. Кроме того, рассмотрите возможность использования 'StringBuilder' при добавлении данных в строку – ar34z
. Но на самом деле строка не должна есть столько памяти, не так ли? Какое преимущество я должен использовать StringBuilder? И как мне настроить его примерно? – Cyaena
Я не тот человек, который объясняет использование памяти, но хранит 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