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

问题

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

java.lang.OutOfMemoryError: GC overhead limit exceeded

我知道OutOfMemoryError是什么,但GC开销限制意味着什么?我该如何解决这个问题?


#1 热门回答(604 赞)

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

这实际上意味着你的程序停止执行任何进度,并且一直忙着只运行垃圾收集。

为了防止应用程序在没有完成任何操作的情况下吸收CPU时间,JVM会抛出这个“错误”,以便你有机会诊断问题。

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

有关详细信息,请查看this article(具体为this part)。


#2 热门回答(163 赞)

当垃圾收集花费太多时间以获得太少的回报时,GC会抛出此异常,例如。在GC上花费了98%的CPU时间,并且恢复了不到2%的堆。

此功能旨在防止应用程序长时间运行,同时由于堆太小而很少或没有进度。

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

更多信息here

编辑:看起来有人可以比我更快打字:)


#3 热门回答(76 赞)

如果你确定你的计划中没有memory leaks,请尝试:

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

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