【问题标题】:java.lang.OutOfMemoryError: GC overhead limit exceeded while Reading a Large Text filejava.lang.OutOfMemoryError:读取大文本文件时超出 GC 开销限制
【发布时间】:2017-02-09 10:11:19
【问题描述】:

我有一个大小约为 2 GB 的文本文件。文件的每一行格式如下:

一些文本可能用逗号分隔,唯一整数

我需要把每一行,分成两部分: 文本,唯一整数,并将其作为键值对放入 Hashmap 中。

现在,即使堆大小设置为 10 GB,我也面临 OutOfMemory 错误。

这可能有两个原因: 1.我读取文件的方式不对。 2. 我创建了太多不必要的 String 对象。

这就是我正在做的:

InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("filename.txt");

InputStreamReader stream = new InputStreamReader(is, StandardCharsets.UTF_8);

BufferedReader reader = new BufferedReader(stream);

while(true)
{
 line =reader.readLine();
 if (line == null) {
  break;
 }
 String text= line.substring(0, line.lastIndexOf(",")).trim();

 String id = line.substring(line.lastIndexOf(",") + 1).trim();

 //put this in a hashmap and other processing
}

由于我需要将文本的每一行分成两部分,并且第一部分(文本)也可能有逗号,因此我为此目的使用了 substring() 方法。

我使用 trim 的原因是我需要将 text 和 id 放在 Hashmap 中,而不需要尾随和前导空格。

错误信息:

 Caused by: java.lang.OutOfMemoryError: GC overhead limit exceeded
    at java.util.Arrays.copyOfRange(Arrays.java:3664)
    at java.lang.String.<init>(String.java:207)
    at java.lang.String.substring(String.java:1969)

【问题讨论】:

  • 不要将整个文件读入内存。一次处理一行。如果不能,说明文件设计有问题,或者您应该使用数据库。
  • @EJP 我该怎么做?
  • 为什么不将输出写入新文件?你甚至可以把它写成 JSON,它实际上是一张地图。
  • @ayahuasca 我正在处理现有的代码库。我认为问题可能出在上面的代码中。
  • @ak0817 你是怎么做的?一次读取一行文件?一次处理一行?

标签: java string file-io garbage-collection


【解决方案1】:

你应该添加循环条件。请用下划线代码再试一次。它似乎工作!

    try {
        String line;

        while ((line = reader.readLine()) != null) {
            String text = line.substring(0, line.lastIndexOf(",")).trim();

            String id = line.substring(line.lastIndexOf(",") + 1).trim();

            //put this in a hashmap and other processing
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            reader.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

【讨论】:

  • 更新了代码。谢谢,但问题是别的。
  • 你能简单描述一下问题还是粘贴一些东西
  • 你的循环条件是line == null,和OP现有的循环终止条件完全一样。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-12-27
  • 1970-01-01
  • 2020-09-08
  • 2020-07-24
  • 1970-01-01
  • 2019-06-29
相关资源
最近更新 更多