我对BlueJ的Java堆空间有一个问题。我已经写了一个程序,它读取一个字符串的.txt,遍历字符串的所有字符,并做一些事情(我猜这并不是真的很重要)。一些.txt真的很大(大约2亿)。如果我尝试用这些.txt执行程序,我会得到这个“线程中的异常"AWT-EventQueue-0”java.lang.OutOfMemoryError: Java heap space“错误代码。我将bluej.def中的bluej.windows.vm.args和bluej.windows.vm.args增加到8 8gb。但它仍然不起作用。但实际上我猜,即使是2亿个字符的字符串也不会超过这个限制。下面是我如何在.txt中读取数据的代码
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
发布于 2016-11-29 20:19:02
在下面的解释中,只有数据的普通内存在作用域中。结构所需的所有额外内存都被省略了。它更像是一个深入细节视图的概览。
记忆在这些行被吃掉了。
String parcour = "";
...
String line = bReader.readLine();
...
parcour += line;行parcour += line被编译成类文件,如下所示
new StringBuilder().append(parcour).append(line).toString()假设parcour包含一个大小为10MB的字符串,而line的大小为2MB。那么在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()在将新创建的字符串分配给大约34MB的parcour之前,您的代码需要。
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个字符的字符串,直到抛出OutOfMemoryException为止。为了加快速度,我们将堆大小限制为10MB。
java -Xmx10m OOMString的输出
length = 1048000
Exception in thread "main" java.lang.OutOfMemoryError: Java heap spacejava -Xmx10m OOMStringBuilder的输出
length = 2052000
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space当您执行这些代码时,您会注意到,与OOMStringBuilder相比,OOMString需要更多的时间才能失败(即使失败的时间更短)。
您还需要记住,单个字符的长度为两个字节。如果您的文件包含100个ASCII字符,它们将占用200字节的内存。
也许这个小演示可以为你解释一下。
发布于 2017-04-25 14:27:20
我在BlueJ和堆空间错误方面也遇到了一些问题。在我的例子中,打开终端会使整个应用程序崩溃。我怀疑这与生成大量输出有关,类似于您的大字符串。在我的例子中,我意外地在某个地方创建了一个无限循环,打破了终端窗口。
我不得不删除所有的属性文件。现在BlueJ又可以工作了,并且不再提供OutOfMemoryErrors。我希望这对其他情况也有帮助。
https://stackoverflow.com/questions/40846059
复制相似问题