超出了Java GC开销限制 - 需要自定义解决方案

时间:2013-05-31 20:04:18

标签: java arrays performance out-of-memory overhead

我正在用相当大的算法评估文本文件中的不同数据。

如果文本文件包含的数据点超过数据点(我需要的最小值是130万个数据点),则会出现以下错误:

Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceeded
   at java.util.regex.Matcher.<init>(Unknown Source)
   at java.util.regex.Pattern.matcher(Unknown Source)
   at java.lang.String.replaceAll(Unknown Source)
   at java.util.Scanner.processFloatToken(Unknown Source)
   at java.util.Scanner.nextDouble(Unknown Source)

当我在Eclipse中运行它时,安装的jre6(标准VM)具有以下设置:

-Xms20m -Xmx1024m -XX:MinHeapFreeRatio=20 -XX:MaxHeapFreeRatio=40 -XX:NewSize=10m 
-XX:MaxNewSize=10m -XX:SurvivorRatio=6 -XX:TargetSurvivorRatio=80 
-XX:+CMSClassUnloadingEnabled

请注意,如果我只运行部分文本文件,它可以正常工作。

现在我已经阅读了很多关于这个主题的内容,似乎某个地方我必须有数据泄漏或者我在数组中存储了太多数据(我认为我这样做)。

现在我的问题是:我该如何解决这个问题?

  • 是否可以更改我的设置,以便我仍然可以执行计算,还是我真的需要更多的计算能力? (不知道从哪里得到)
  • 我在某处读到,最好使用id和指针作为CPU,而不是将数据放入数组并让它处理它。但是,如何更改我的代码,使其仅提供指针?

基本上我正在寻找防止大量内存存储/泄漏的一般指导原则。

3 个答案:

答案 0 :(得分:3)

真正关键的vm arg是-Xmx1024m,它告诉VM最多使用1024兆字节的内存。最简单的解决方案是在那里使用更大的数字。假设您的计算机中有足够的RAM来处理它,您可以尝试-Xmx2048m-Xmx4096m或任意数字。

我不确定你是否从其他任何VM args中获得了很多好处。在大多数情况下,如果你告诉Java要使用多少空间,那么其他参数就会很聪明。我建议删除除-Xmx param之外的所有内容,看看它是如何执行的。

更好的解决方案是尝试改进您的算法,但我还没有详细阅读它以提供任何建议。

答案 1 :(得分:3)

正如你所说的那样,数据大小真的非常大,如果它甚至在使用-Xmx jvm参数后仍然不适合一台计算机内存,那么你可能想要转移到集群计算,使用许多计算机工作你的问题。为此,您必须使用消息传递接口(MPI)。

MPJ Express是Java的MPI非常好的实现,或者像C / C ++这样的语言,MPI存在一些很好的实现,例如Open MPI和{{} 1}}。我不确定它是否会在这种情况下对你有所帮助,但肯定会在未来的项目中帮助你。

答案 2 :(得分:1)

我建议你

  • 使用分析器来最小化您的内存使用量。我怀疑你可以通过使用原语,二进制数据和更紧凑的集合将它减少10倍或更多。
  • 增加机器内存。我最后一次对数百个信号进行测试时,我有256 GB的主内存,这有时几乎不够。记忆越多越好。
  • 使用内存映射文件来提高内存效率。
  • 将数据集的大小减小到机器和程序可以支持的时间。