【问题标题】:OutofMemory LinkedList Adding ErrorOutofMemory LinkedList 添加错误
【发布时间】:2011-03-04 11:49:46
【问题描述】:

我正在尝试从 txt 文件(书)中读取,然后将其每一行添加到链表中。但是,当我运行代码时,l.add(line); 出现内存不足错误。你能告诉我这段代码我做错了什么吗?或者,有没有更好的方法来存储字符串值而不是 LinkedList?

非常感谢!

public Book (String bookname) throws java.io.IOException{
    f = new FileReader(bookname);
    b = new BufferedReader(f);
    l = new LinkedList<String>();
    String line = b.readLine();
    while (line != null) {
        l.add(line);
    }
    b.close();
}

【问题讨论】:

    标签: java out-of-memory bufferedreader filereader linked-list


    【解决方案1】:

    正如其他人指出的那样,您创建了一个无限的、消耗内存的循环。从 BufferedReader 读取的常见习惯用法是:

    String line;
    while ( ( line = b.readLine() ) != null) {
        l.add(line);
    }
    

    我想这本书的内容可能太大而无法一次全部放入记忆中。您可以通过使用 Xmx 参数来增加 JVM 可用的内存,即:

    java -Xmx1G MyClass
    

    它的默认值为 64 Mb,这在当今并不多。

    【讨论】:

      【解决方案2】:

      你一遍又一遍地添加同一行,直到内存耗尽:

      String line = b.readLine();
      while (line != null) {
          l.add(line);
      }
      

      看到了吗? line-变量在循环外读取,在循环内永远不会改变。

      【讨论】:

        【解决方案3】:

        或许你应该替换

        while (line != null) {
            l.add(line);
        }
        

        while (line = b.readLine()) {
            l.add(line);
        }
        

        【讨论】:

          【解决方案4】:

          虽然循环永远不会退出,因为变量 line 永远不会为空。试试这个:

          String line = "";
          while ((line = b.readLine())!= null)
          {
             l.add(line);
          }
          b.close();
          

          【讨论】:

            【解决方案5】:

            很简单,存储字符串(以及程序中的所有其他内容)所需的内存超过了堆上可用的总可用内存。

            其他列表的开销会略有不同,但实际上结构本身的内存需求与其包含的数据相比可能微不足道。换句话说,切换到不同的列表实现可能会让你在跌倒之前多读几行,但这并不能解决问题。

            如果您没有增加 java 应用程序的堆空间,它可能会以相当低的默认值运行。在这种情况下,您应该考虑为您的 java 调用提供以下命令行参数:

            -Xmx512m
            

            512m 表示 512 MB 的堆空间;您可以使用例如 -Xmx2g 或您认为合适的任何其他内容。)

            另一方面,如果你已经在运行一个大堆(比你想在内存中保存的字符串的总大小大得多),这可能指向其他地方的内存问题。书中有多少人物?存储所有行需要至少两倍的字节数,并且可能比这多出 20% 左右才能考虑开销。如果您的计算表明您当前的堆空间应该能够保存所有这些数据,那么其他地方可能会出现一些问题。否则,您现在知道需要将堆增加到最低限度。

            (顺便说一句,尝试将大量输入作为单个批次处理通常会遇到内存问题 - 如果您想处理 8GB 文本文件怎么办?通常最好以某种顺序处理较小的块流。例如,如果您想将每个字符大写并将其写回不同的文件,您可以一次执行一行,而不是先将整本书读入内存。)

            【讨论】:

              【解决方案6】:

              我同意 mjg123。并注意内存不足的预期。我要求您查看此博客以获取有关如何处理此类情况的更多详细信息 Click here

              【讨论】:

                猜你喜欢
                • 2016-02-12
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2013-03-09
                • 1970-01-01
                • 1970-01-01
                • 2016-11-26
                相关资源
                最近更新 更多