在下面的说明中,只有数据的纯内存在范围内。所有额外的内存需求的结构被遗漏。这是更详细的概述。
存储器被在那些线
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