首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >BlueJ的Java堆空间

BlueJ的Java堆空间
EN

Stack Overflow用户
提问于 2016-11-28 21:56:52
回答 2查看 831关注 0票数 0

我对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中读取数据的代码

代码语言:javascript
复制
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

EN

回答 2

Stack Overflow用户

发布于 2016-11-29 20:19:02

在下面的解释中,只有数据的普通内存在作用域中。结构所需的所有额外内存都被省略了。它更像是一个深入细节视图的概览。

记忆在这些行被吃掉了。

代码语言:javascript
复制
String parcour = "";
...
String line = bReader.readLine();
...
parcour += line;

parcour += line被编译成类文件,如下所示

代码语言:javascript
复制
new StringBuilder().append(parcour).append(line).toString()

假设parcour包含一个大小为10MB的字符串,而line的大小为2MB。那么在parcour += line;期间分配的内存将是(大致)

代码语言:javascript
复制
// 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之前,您的代码需要。

代码语言:javascript
复制
parcour                            = 10 MB
the temporary StringBuilder object = 12 MB
the String fromStringBuilder       = 12 MB
------------------------------------------
total                                34 MB

这是一个小的演示片段,展示了OutOfMemoryException抛出的时间比您当前预期的要早得多。

OOMString.java

代码语言:javascript
复制
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

代码语言:javascript
复制
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的输出

代码语言:javascript
复制
length = 1048000
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space

java -Xmx10m OOMStringBuilder的输出

代码语言:javascript
复制
length = 2052000
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space

当您执行这些代码时,您会注意到,与OOMStringBuilder相比,OOMString需要更多的时间才能失败(即使失败的时间更短)。

您还需要记住,单个字符的长度为两个字节。如果您的文件包含100个ASCII字符,它们将占用200字节的内存。

也许这个小演示可以为你解释一下。

票数 0
EN

Stack Overflow用户

发布于 2017-04-25 14:27:20

我在BlueJ和堆空间错误方面也遇到了一些问题。在我的例子中,打开终端会使整个应用程序崩溃。我怀疑这与生成大量输出有关,类似于您的大字符串。在我的例子中,我意外地在某个地方创建了一个无限循环,打破了终端窗口。

我不得不删除所有的属性文件。现在BlueJ又可以工作了,并且不再提供OutOfMemoryErrors。我希望这对其他情况也有帮助。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40846059

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档