如何解决'java.lang.OutOfMemoryError: GC overhead limit exceeded'错误

3
我阅读了关于解决这个问题的这个stackoverflow页面,并尝试添加命令行选项-XX:-UseGCOverheadLimit和“-Xmx”参数。然而,我的程序仍然抛出了内存不足错误。
该程序将大量(> 40,000个键)单词保存到MultiKeyMap中,并在具有足够内存的服务器上运行。
你有任何关于如何避免此错误的建议吗?

1
你使用 -Xmx 设置了多少内存? - Subir Kumar Sao
你需要对你的代码进行分析,以查明为什么它会如此快地产生大量垃圾。 - Joachim Sauer
4万个键听起来不算多。我建议您对应用程序进行内存分析,以查明为什么它使用了这么多内存。 - Peter Lawrey
3个回答

4
如果您的问题可以可靠地缩小范围(即使不能),我建议激活-XX:+HeapDumpOnOutOfMemoryError JVM标志。当发生OutOfMemoryError时,这将生成内存的二进制转储。然后可以使用诸如Eclipse MAT之类的工具对其进行分析,以确定可能存在的内存泄漏,并帮助解释为什么垃圾收集器很难清除对象。

+1 -XX:-HeapDumpOnOutOfMemoryError 是关闭状态并且是默认选项。要开启它,您需要使用 -XX:+HeapDumpOnOutOfMemoryError。在文档中,它总是显示默认选项,这意味着如果您复制该选项,则不应执行任何操作。(在我看来非常令人困惑)您必须将“-”切换为“+”,反之亦然才能实现某些功能。 - Peter Lawrey
我的错 - 我总是记不住精确的调用方式,所以我搜索了它并复制了谷歌返回的第一个片段,甚至没有点击链接查看上下文。我会纠正它。 - Rich
1
我已经根据@PeterLawrey的建议编辑了答案,更改了标志。 - Rich

1
这个问题意味着垃圾回收器无法释放足够的内存供您的应用程序继续运行。因此,即使您使用“XX:-UseGCOverheadLimit”关闭了特定的警告,您的应用程序仍将崩溃,因为它消耗的内存超过了可用内存。
我认为您有内存泄漏的症状。可以尝试像另一个答案建议的那样挖掘内存转储,或者尝试使用Plumbr,这是一种专门针对这些情况创建的内存泄漏监测工具。

0
“GC Overhead limit” 可能与内存泄漏有关,但不一定是这种情况。根据原始问题,很难说出真正的问题所在。您应该使用“普通”的命令行配置,而不是所有神秘的标志,并设置合理的 Xmx 值来保存所有数据。您应该激活详细的 GC 日志记录以了解实际导致开销的 GC 并通过更改 GC 策略或代大小来进行调整。
通常,在使用试图具有内存友好性并使用软引用或弱引用的结构时,会出现超额错误。如果您自己使用它们,请仔细检查您是否了解它们的作用,因为它们很容易被误解。

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