当我执行JUnit测试时,我得到了这个错误消息:

java.lang.OutOfMemoryError: GC overhead limit exceeded

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


当前回答

在Netbeans中,设计最大堆大小可能会有所帮助。执行命令Run =>设置项目配置=>自定义。在弹出窗口的运行中,进入虚拟机选项,填写-Xms2048m -Xmx2048m。它可以解决堆大小的问题。

其他回答

这条消息意味着由于某种原因,垃圾收集器花费了过多的时间(默认情况下占进程所有CPU时间的98%),并且在每次运行中回收的内存非常少(默认情况下占堆时间的2%)。

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

为了防止应用程序占用CPU时间而不做任何事情,JVM抛出这个错误,以便您有机会诊断问题。

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

请查看Java GC调优指南,该指南可用于各种Java版本,其中包含关于此特定问题的部分:

Java 11调优指南中有针对不同垃圾收集器的过量GC的专门章节: 用于并联集热器 用于同步标记扫描(CMS)收集器 对于垃圾优先(G1)收集器,没有提到这种特定的错误条件。 Java 8调优指南及其过量GC部分 Java 6调优指南及其过量GC部分。

引用Oracle的文章“Java SE 6 HotSpot[tm]虚拟机垃圾收集调优”:

Excessive GC Time and OutOfMemoryError The parallel collector will throw an OutOfMemoryError if too much time is being spent in garbage collection: if more than 98% of the total time is spent in garbage collection and less than 2% of the heap is recovered, an OutOfMemoryError will be thrown. This feature is designed to prevent applications from running for an extended period of time while making little or no progress because the heap is too small. If necessary, this feature can be disabled by adding the option -XX:-UseGCOverheadLimit to the command line.

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

通过设置这个选项,稍微增加堆的大小

运行→运行配置→参数→虚拟机参数

-Xms1024M -Xmx2048M

Xms—用于最小限制

Xmx -表示最大限制

您可以尝试通过参考此映像来更改服务器设置,并增加用于处理的内存大小 流程更改以黄色突出显示

你也可以通过打开cmd-> set _java_opts - xmx2g来改变java堆 2g(2gb),这取决于程序的复杂程度

尽量少使用常数变量和临时变量

@Buhb 我在一个普通的spring-boot web应用程序的main方法中复制了这个过程。代码如下:

public static void main(String[] args) {
    SpringApplication.run(DemoServiceBApplication.class, args);
    LOGGER.info("hello.");
    int len = 0, oldlen=0;
    Object[] a = new Object[0];
    try {
        for (; ; ) {
            ++len;
            Object[] temp = new Object[oldlen = len];
            temp[0] = a;
            a = temp;
        }
    } catch (Throwable e) {
        LOGGER.info("error: {}", e.toString());
    }
}

引起come的示例代码也是来自oracle java8语言规范。