如何在Java中的内存密集型应用程序中避免OutOfMemory异常?

时间:2014-01-16 19:41:31

标签: java hadoop memory-leaks out-of-memory

我们开发了一个java应用程序,其主要目标是读取文件(输入文件),处理它并将其转换为输出文件集。

(我已经给出了我们解决方案的一般描述,以避免不相关的细节。)

当输入文件为4 GB,内存设置为-Xms4096m -Xmx16384m(32 GB RAM)时,此程序可以正常工作

现在我们需要使用大小为130 GB的输入文件来运行我们的应用程序。

我们使用了一个带250GB RAM的Linux机箱,内存设置为-Xms40g -Xmx200g(也尝试了其他几种变体)来运行应用程序并点击OutOfMemory Exception。

在我们项目的这个阶段,很难考虑重新设计代码以适应hadoop(或其他大规模数据处理框架),我们能够承受的当前硬件配置是250GB RAM。

请您建议我们避免OutOfMemory Exceptions的方法,开发这类应用程序时的一般做法是什么。

提前致谢

2 个答案:

答案 0 :(得分:1)

最明显的尝试是不将整个文件保留在内存中(如果可能)。因此,您可以在块中处理它,并且在任何时刻只在内存中保留一个或几个块(而不是整个文件)。

答案 1 :(得分:1)

尝试继续使用尽可能少的内存,比如说,不要将整个文件保存在内存中,将其转储到磁盘上。

说,Hadoop HDFS为您做到这一点,只需通过优秀的分析器或堆转储分析器检查您是否有任何泄漏。

自定义解决方案可能仍然是使用普通文件,但是以页面方式组织访问。例如。 Java具有良好的MappedByteBuffer,可以让你将文件的某个部分加载到内存中以便更快地访问(它在Java 7之前有一些问题,导致不可预测的取消映射,但据我所知它已被修复)。