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

java.lang.OutOfMemoryError: GC overhead limit exceeded

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


当前回答

@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语言规范。

其他回答

引用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.

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

通常是代码。这里有一个简单的例子:

import java.util.*;

public class GarbageCollector {

    public static void main(String... args) {

        System.out.printf("Testing...%n");
        List<Double> list = new ArrayList<Double>();
        for (int outer = 0; outer < 10000; outer++) {

            // list = new ArrayList<Double>(10000); // BAD
            // list = new ArrayList<Double>(); // WORSE
            list.clear(); // BETTER

            for (int inner = 0; inner < 10000; inner++) {
                list.add(Math.random());
            }

            if (outer % 1000 == 0) {
                System.out.printf("Outer loop at %d%n", outer);
            }

        }
        System.out.printf("Done.%n");
    }
}

在Windows 7 32位操作系统上使用Java 1.6.0_24-b07。

java -Xloggc:gc.log GarbageCollector

然后查看gc.log

使用BAD方法触发444次 使用WORSE方法触发666次 使用BETTER方法触发354次

现在承认,这不是最好的测试或最好的设计,但当你面临别无选择只能实现这样的循环或处理行为糟糕的现有代码时,选择重用对象而不是创建新对象可以减少垃圾收集器阻碍的次数……

要在IntelliJ IDEA中增加堆大小,请遵循以下说明。这对我很管用。

对于Windows用户,

转到安装IDE的位置并搜索以下内容。

idea64.exe.vmoptions

编辑该文件并添加以下内容。

-Xms512m
-Xmx2024m
-XX:MaxPermSize=700m
-XX:ReservedCodeCacheSize=480m

就是这样!!

我在使用Oracle web逻辑服务器时得到了这个错误。我分享我的答案作为参考,以防有人最终在这里寻找解决方案。

所以,如果你试图提升Oracle web逻辑服务器并得到这个错误,那么你只需要增加运行服务器的初始和最大堆大小。

转到- > C:\Oracle\Middleware\Oracle_Home\user_projects\domains\wl_server\bin 打开setDomainEnv.cmd 检查设置USER_MEM_ARGS值,如果小于 set USER_MEM_ARGS="- xms128m - Xmx8192m ${MEM_DEV_ARGS} ${MEM_MAX_PERM_SIZE}"

这意味着初始堆大小设置为128 MB,最大堆大小为8GB。 现在,只需保存文件并重新启动服务器。如果不能解决问题,请尝试增加大小或寻找优化服务的方法。

参考,检查这个链接:https://docs.oracle.com/cd/E49933_01/server.770/es_install/src/tins_postinstall_jvm_heap.html

edit:检查您是否能够在运行服务器时看到更新的java参数。就像这样 如果它像以前一样,那么替换setDoaminEnv中显示的值。CMD由简单的搜索和替换。

在build.gradle(Module:app)文件中增加javaMaxHeapsize

dexOptions {
    javaMaxHeapSize "1g"
}

to(在gradle中添加这一行)

 dexOptions {
        javaMaxHeapSize "4g"
    }