Java GC超过限制 - 需要自定义解决方案

7

我正在评估一个相当复杂的算法中来自文本文件的不同数据。

如果文本文件包含超过数据点(最低要求大约是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

请注意,如果我只运行部分文本文件,它可以正常工作。
现在我已经阅读了很多关于这个主题的内容,似乎我必须要么有数据泄漏,要么是我在数组中存储了太多数据(我认为是这样)。
现在我的问题是:我该如何解决这个问题?是否可以更改设置以便我仍然可以执行计算,还是我真的需要更多的计算能力?

我们怎样才能确信您准确理解它的含义?我们只知道您认为如此。 - Marko Topolnik
我看到这个:https://dev59.com/anM_5IYBdhLWcg3wZSTX - Jean-Paul
2
我认为你需要使用性能分析器。我特别推荐visualgc。 - Marko Topolnik
1
具体来说,visualgc实时可视化所有堆生成。您可以直观地看到每个分配和GC方面的情况。它使您能够快速形成有关可能出错的假设。 - Marko Topolnik
你有一些大型数据的示例吗?这是一个相当有趣的问题,但复制数据以测试解决方案可能成为一个问题... - fge
显示剩余2条评论
3个回答

3
真正关键的vm arg是-Xmx1024m,它告诉虚拟机可使用最多1024兆字节的内存。最简单的解决方案是在这里使用更大的数字。您可以尝试-Xmx2048m-Xmx4096m或任何数字,假设您的机器有足够的RAM来处理它。
我不确定您是否从其他VM args中获得了很多好处。就大多数情况而言,如果您告诉Java要使用多少空间,它会用其余参数进行智能操作。我建议除了-Xmx参数之外移除所有参数,看看效果如何。
更好的解决方案是尝试改进您的算法,但我还没有详细阅读它以提供任何建议。

那听起来很有道理。所以我大约有4个RAM。这意味着我应该能够将-Xmx增加到大约2048?我明天会尝试并告诉你是否有效。(这里是晚上) - Jean-Paul
2
正确。如果你很幸运的话,这对于你的数据集来说可能足够了,你就不需要再去烦恼更困难或耗时的改变了。总共有4GB的内存,你可能可以在虚拟机中使用3GB,尽管你可能需要关闭一些其他程序。 - Eric Grunzke
如果它能工作,我会把分数给你,因为你提供了一个非常简短但高效的解决方案。 - Jean-Paul
成功了!我不知道增加内存可以解决这个错误。我以为它只与堆大小错误有关!非常感谢您的答案! - Jean-Paul

3
由于您所提到的数据大小非常大,即使使用了-Xmx JVM参数后仍无法适应计算机内存,因此您可能需要转向集群计算,使用许多计算机来处理您的问题。为此,您将需要使用消息传递接口(MPI)。

MPJ Express是Java的一个非常好的MPI实现,在类似于C/C++的语言中,也有一些良好的MPI实现,如Open MPImpich2。我不确定它是否能帮助您解决当前的问题,但肯定会在未来的项目中有所帮助。


谢谢!很好的替代选择! - Jean-Paul

1
我建议您:
  • 使用性能分析器来最小化内存使用。我怀疑使用原始数据、二进制数据和更紧凑的集合可以将其减少10倍或更多。
  • 增加计算机内存。上次我进行数百个信号的回测时,我有256GB的主内存,有时这还不够用。您获得的内存越多,效果越好。
  • 使用内存映射文件以提高内存效率。
  • 缩小数据集的大小,以适应您的计算机和程序。

“256 GB的主存储器”是什么意思? - Jean-Paul
这台机器有256GB的内存,使用内存映射文件时我几乎用了全部。 - Peter Lawrey
哇!那肯定是一个非常大的项目。不,我最大的文件(一个作为数据库的.txt文件)大约有70兆字节,所以没问题。虽然我已经将它设置为1024m,但我解决了我的问题,比我想象的简单:我只需要增加Eclipse允许使用的最大内存即可。我对这些“内存映射文件”很感兴趣,所以我会研究一下以备将来使用。谢谢你的时间和回答! - Jean-Paul

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接