超出 Java GC 开销限制 - 需要自定义解决方案
Posted
技术标签:
【中文标题】超出 Java GC 开销限制 - 需要自定义解决方案【英文标题】:Java GC overhead limit exceeded - Custom solution needed 【发布时间】:2013-05-27 17:38:00 【问题描述】:我正在一个相当大的算法中评估来自文本文件的不同数据。
如果文本文件包含多个数据点(我需要的最小值是 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
请注意,如果我只运行部分文本文件,它就可以正常工作。
现在我已经阅读了很多关于这个主题的内容,似乎我必须在某个地方发生数据泄漏,或者我在数组中存储了太多数据(我想我确实这样做了)。
现在我的问题是:我该如何解决这个问题?是否可以更改我的设置以便我仍然可以执行计算,还是我真的需要更多的计算能力?
【问题讨论】:
我们如何确定您确切知道它的含义?我们所拥有的只是您这么认为。 我读到这个:***.com/questions/1393486/… 我认为您应该为此需要分析器的服务。我特别推荐visualgc。 分析器到底是做什么的?我以前从未使用过它.. 具体来说,visualgc 实时可视化所有堆代。您可以准确直观地看到分配和 GC 的各个方面发生了什么。它使您可以快速制定有关可能出现问题的假设。 【参考方案1】:真正关键的 vm arg 是 -Xmx1024m
,它告诉 VM 最多使用 1024 兆字节的内存。最简单的解决方案是在那里使用更大的数字。您可以尝试-Xmx2048m
或-Xmx4096m
或任何数字,前提是您的计算机中有足够的内存来处理它。
我不确定您是否从任何其他 VM 参数中获得了很多好处。在大多数情况下,如果你告诉 Java 要使用多少空间,它会很聪明地处理其余的参数。我建议删除除 -Xmx
参数之外的所有内容并查看其执行情况。
更好的解决方案是尝试改进您的算法,但我还没有仔细阅读它以提供任何建议。
【讨论】:
这似乎有道理。所以我有大约 4 个 RAM。所以这意味着我应该能够将 -Xmx 增加到大约 2048?我明天会试试,如果它有效,请告诉你。 (这里是晚上) 正确。如果你幸运的话,这对你的数据集来说就足够了,你不需要为更困难/更耗时的更改而烦恼。总共 4GB,您的 vm 中可能最多可以达到 3GB,但您可能需要关闭一些其他程序。 如果可行,我会为您提供一个非常简短但有效的解决方案 成功了!我不知道增加内存可以解决这个错误。我认为它只与堆大小错误有关!非常感谢您的回答!【参考方案2】:我建议你
使用分析器来最大限度地减少内存使用量。我怀疑您可以通过使用基元、二进制数据和更紧凑的集合将其减少 10 倍或更多。 增加您机器的内存。上次我对数百个信号进行回测时,我有 256 GB 的主内存,这有时还不够。您可以获得的内存越多越好。 使用内存映射文件来提高内存效率。 将数据集的大小减少到机器和程序可以支持的时间。【讨论】:
“256 GB 主内存”是什么意思。 这台机器有 256 GB 的内存并且使用了我几乎所有的内存映射文件。 哇!那一定是一个非常大的项目。没有我最大的文件(一个用作数据库的 .txt 文件)大约 70 mb,所以我很好。不过我解决了我的问题,比我想象的要简单:我只需要增加 Eclipse 允许使用的最大内存(即使我已经把它设置为 1024m)。我对这些“内存映射文件”很感兴趣,所以我会读到它以备将来使用。感谢您的时间和回答!【参考方案3】:正如您所说,数据量确实非常大,如果即使在使用-Xmx
jvm 参数后它仍无法放入一台计算机的内存中,那么您可能希望转移到集群计算,使用多台计算机在您的问题。为此,您必须使用消息传递接口 (MPI
)。
MPJ Express
是 Java 中 MPI
的一个非常好的实现,或者在 C/C++ 等语言中,MPI
存在一些好的实现,例如 Open MPI
和 mpich2
。我不确定它在这种情况下是否会帮助你,但肯定会在未来的项目中帮助你。
【讨论】:
谢谢!不错的选择!以上是关于超出 Java GC 开销限制 - 需要自定义解决方案的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 maven jvmArg 解决“超出 GC 开销限制”?
布局 xml 上的 Java 堆空间错误:超出 GC 开销限制
Pyspark:java.lang.OutOfMemoryError:超出 GC 开销限制