【发布时间】: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