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

java.lang.OutOfMemoryError: GC overhead limit exceeded

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


当前回答

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

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

-Xms1024M -Xmx2048M

Xms—用于最小限制

Xmx -表示最大限制

其他回答

下面的方法对我很有效。只需添加以下片段:

android {
        compileSdkVersion 25
        buildToolsVersion '25.0.1'

defaultConfig {
        applicationId "yourpackage"
        minSdkVersion 10
        targetSdkVersion 25
        versionCode 1
        versionName "1.0"
        multiDexEnabled true
    }
dexOptions {
        javaMaxHeapSize "4g"
    }
}

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

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

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

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

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

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

解决: 只需添加 org.gradle.jvmargs = -Xmx1024m 在 gradle.properties 如果它不存在,那就创造它。

您还可以通过将此添加到gradle中来增加内存分配和堆大小。属性文件:

org . gradle。jvmargs = -Xmx2048M -XX: MaxHeapSize \ = 32g

它不需要2048M和32g,你想要多大就有多大。