如何优化大文件处理的内存使用量

时间:2016-06-02 01:49:53

标签: java heap-memory

我有一个文件,我从文件填充HashMap<String, ArrayList<Objects>>。 HashMap的大小肯定是25,意味着25个密钥,但每个密钥的List将是巨大的百万条记录。

所以我现在要做的就是为每个键检索记录列表并使用线程并行处理它们。事情继续发展,直到我面对更大的文件,所以我面对“java.lang.OutOfMemoryError:Java堆空间”。

我想问一下,用对象列表填充HashMap的最佳方法是什么?我想要的是获取文件的25个偏移,而不是将我从文件中读取的行放入arrayList,放置文件的偏移量,并给每个线程一个迭代器,从其起始偏移量到结束偏移量进行迭代。我仍然要尝试这个想法。但在执行之前,我想知道更好的内存使用方法。

2 个答案:

答案 0 :(得分:1)

  

我将填充HashMap<String, ArrayList<Objects>>

填充HashMap后你需要做些什么?我相信只是填充地图不是你的任务。无论什么情况,您都不需要在内存中读取整个文件。

增加堆大小可能不是一个好的解决方案,因为有一天你可能会得到一个比你的堆大小更大的文件。

根据您的需要,使用*BufferedReader以块的形式阅读文件,并在阅读时执行任务。这两个API一次只读取内存中文件的一部分。

  

我从文件中读取到arrayList,放入文件的偏移量,并给每个线程一个迭代器,从其起始偏移量到结束偏移量进行迭代。我仍然要尝试这个想法。

使用多个线程不会阻止java.lang.OutOfMemoryError,因为所有线程都在同一个JVM中。此外,无论您是在一个列表还是多个列表中读取文件,该文件中的所有数据都将被读入同一堆内存中。

如果你提到你真正想对文件中的数据做什么,这个答案可能更具体。

答案 1 :(得分:0)

同样的说法。需要更多信息。您打算如何处理地图?这是一个需要将整个文件加载到内存的操作吗?或者它可以部分完成吗?

另外,您是否考虑过将文件大小超过阈值大小后将其拆分为多个部分?

像Pshemo的回答一样:How to break a file into pieces using Java?

此外,如果要并行处理,可以考虑处理覆盖文件一部分的地图。并行映射的进程,并将结果存储在某种队列中。如果队列将包含您正在处理的数据的子集(以避免OutOfMemory异常)。