协慌网

登录 贡献 社区

错误 java.lang.OutOfMemoryError:超出了 GC 开销限制

执行 JUnit 测试时,我收到此错误消息:

java.lang.OutOfMemoryError: GC overhead limit exceeded

我知道什么是OutOfMemoryError ,但是 GC 开销限制是什么意思?我该如何解决?

答案

此消息表示由于某种原因,垃圾收集器占用了过多的时间(默认情况下为该进程所有 CPU 时间的 98%),并且每次运行时恢复的内存很少(默认为堆的 2%)。

这实际上意味着您的程序停止任何进展,并且一直在忙于仅运行垃圾回收。

为了防止您的应用程序浪费 CPU 时间而不做任何事情,JVM 抛出此Error以便您有机会诊断问题。

我见过这种情况的罕见情况是,某些代码在已经非常受内存限制的环境中创建了大量的临时对象和大量的弱引用对象。

查看 Java GC 调整指南,该指南可用于各种 Java 版本,并且包含有关此特定问题的部分:

当在垃圾回收上花费太多时间而返回的次数太少时,GC 就会抛出此异常。 GC 上花费了 98%的 CPU 时间,并且不到 2%的堆被恢复。

此功能旨在防止应用程序长时间运行,而由于堆太小而几乎没有进展,甚至没有进展。

您可以使用命令行选项-XX:-UseGCOverheadLimit将其关闭-XX:-UseGCOverheadLimit

更多信息在这里

编辑:看起来有人可以比我快输入:)

如果您确定程序中没有内存泄漏 ,请尝试:

  1. 增加堆大小,例如-Xmx1g
  2. 启用并发的低暂停时间收集器-XX:+UseConcMarkSweepGC
  3. 尽可能重用现有对象以节省一些内存。

如有必要,可以通过在命令行中添加选项-XX:-UseGCOverheadLimit来禁用限制检查