我在一个相当大的算法中评估来自文本文件的不同数据。
如果文本文件包含多个数据点(我需要的最小值是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(标准虚拟机)进行以下设置:
-Xms20m -Xmx1024m -XX:MinHeapFreeRatio=20 -XX:MaxHeapFreeRatio=40 -XX:NewSize=10m
-XX:MaxNewSize=10m -XX:SurvivorRatio=6 -XX:TargetSurvivorRatio=80
-XX:+CMSClassUnloadingEnabled
请注意,如果我只运行部分文本文件,它可以正常工作。
现在我已经读了很多关于这个主题,似乎在某个地方我必须有数据泄漏或者我在数组中存储了太多的数据(我认为我这样做)。
现在我的问题是:我如何解决这个问题?是否有可能更改我的设置,以便我仍然可以执行计算,或者我真的需要更多的计算能力?
真正关键的vm参数是-Xmx1024m
,它告诉vm使用最多1024兆字节的内存。最简单的解决方法是用一个更大的数。您可以尝试-Xmx2048m
或-Xmx4096m
,或任何数字,假设您的机器中有足够的RAM来处理它。
我不确定您是否从其他VM参数中获得了很多好处。在大多数情况下,如果您告诉Java要使用多少空间,它会很聪明地处理其余的参数。我建议删除除-Xmx
参数外的所有内容,并查看其执行情况。
一个更好的解决方案是尝试改进你的算法,但是我还没有足够详细地阅读它来提供任何建议。
正如您所说的,数据大小确实非常大,如果即使在使用-Xmx
jvm参数后,它也不适合一台计算机的内存,那么您可能想要移动到集群计算,使用许多计算机来处理您的问题。为此,您必须使用消息传递接口(MPI
)。
MPJ Express
是Java中MPI
的一个很好的实现,或者在C/c++等语言中,MPI
有一些很好的实现,如Open MPI
和mpich2
。我不确定它在这种情况下是否会对你有帮助,但肯定会对你将来的项目有帮助。
我建议你
- 使用分析器来最小化内存使用。我怀疑你可以通过使用原语、二进制数据和更紧凑的集合来减少10倍或更多。
- 增加您的机器内存。上次我对数百个信号进行回测时,我的主内存是256gb,有时这几乎不够用。内存越多越好。
- 使用内存映射文件来提高内存效率。
- 将数据集的大小减小到机器和程序可以支持的程度。