在下面的說明中,只有數據的純內存在範圍內。所有額外的內存需求的結構被遺漏。這是更詳細的概述。
存儲器被在那些線
String parcour = "";
...
String line = bReader.readLine();
...
parcour += line;
線parcour += line
吃掉編譯成類文件作爲
new StringBuilder().append(parcour).append(line).toString()
假設parcour
包含大小爲10 MB的字符串和line
將大小的2 MB。然後在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 MB。
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);
}
}
}
兩個片段做同樣的。他們在parcour
中添加了1000個charcater字符串,直到OutOfMemoryException
被引發。爲了加快速度,我們將堆大小限制爲10 MB。
的輸出java -Xmx10m OOMStringBuilder
length = 2052000
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
java -Xmx10m OOMString
length = 1048000
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
輸出當你執行的代碼,你會發現,OOMString
需要更多的時間來失效(甚至在更短的長度)比OOMStringBuilder
。
您還需要記住單個字符是兩個字節長。如果您的文件包含100個ASCII字符,則它們在內存中佔用200個字節。
也許這個小小的演示可以爲你解釋一點點。
您正在將整個文件存儲在'parcour'變量中。這會吃掉很多的記憶。另外,在將數據附加到字符串 – ar34z
時考慮使用'StringBuilder',但實際上String不應該佔用那麼多的內存,不是嗎?我必須使用StringBuilder有什麼優勢?我該如何粗略設置它? – Cyaena
我不是解釋內存使用情況的正確人選,但存儲了200萬個。內存中的字符聽起來不太有希望。在循環中連接字符串時,「StringBuilder」更快。你想用這2億行做什麼?也許這可以幫助你: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