首页 文章

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

提问于
浏览
691

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

java.lang.OutOfMemoryError: GC overhead limit exceeded

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

15 回答

  • 10

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

    这实际上意味着您的程序停止执行任何进度,并且忙于始终只运行垃圾回收 .

    为了防止应用程序在没有完成任何操作的情况下吸收CPU时间,JVM会抛出此 Error ,以便您有机会诊断问题 .

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

    有关详细信息,请查看this article(特别是this part) .

  • -1

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

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

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

    更多信息here

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

  • 26

    如果您确定程序中没有memory leaks,请尝试:

    • 增加堆大小,例如 -Xmx1g .

    • 启用并发低暂停收集器 -XX:+UseConcMarkSweepGC .

    • 尽可能重用现有对象以节省一些内存 .

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

  • 1

    通常是代码 . 这是一个简单的例子:

    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");
        }
    }
    

    使用java 1.6.0_24-b07在Windows7 32位上 .

    java -Xloggc:gc.log GarbageCollector

    然后看看gc.log

    • 使用BAD方法触发444次

    • 使用WORSE方法触发666次

    • 使用BETTER方法触发354次

    现在被授予,这不是最好的测试或最好的设计,但是当遇到除了实现这样的循环或者处理行为不好的现有代码时别无选择的情况时,选择重用对象而不是创建新对象可以减少垃圾收集器挡住的次数......

  • 78

    只需在此处设置此选项,即可稍微增加堆大小

    运行→运行配置→参数→VM参数

    -Xms1024M -Xmx2048M
    

    Xms - 最低限额

    Xmx - 最大限度

  • -1

    原因error

    超出GC开销限制“表示垃圾收集器一直在运行,Java程序进展非常缓慢 .

    在垃圾收集之后,如果Java进程花费超过大约98%的时间进行垃圾收集,并且它正在恢复少于2%的堆并且到目前为止已经执行了最后5个(编译时常量)连续垃圾收集,然后抛出 java.lang.OutOfMemoryError

    • 如果当前堆不够,请增加堆大小 .

    • 如果在增加堆内存后仍然出现此错误,请使用内存分析工具,如MAT(内存分析器工具),Visual VM等,并修复内存泄漏 .

    • 将JDK版本升级到最新版本(1.8.x)或至少1.7.x并使用G1GC算法 . . G1 GC的吞吐量目标是90%的应用程序时间和10%的垃圾回收时间

    • 除了使用 - Xms1g -Xmx2g 设置堆内存外,请尝试

    -XX:+UseG1GC -XX:G1HeapRegionSize=n -XX:MaxGCPauseMillis=m  
    -XX:ParallelGCThreads=n -XX:ConcGCThreads=n
    

    看看有关G1GC的一些更相关的问题

    Java 7 (JDK 7) garbage collection and documentation on G1

    Java G1 garbage collection in production

    Oracle technetwork article for GC finetuning

  • 674

    对我来说,以下步骤有效:

    • 打开 eclipse.ini 文件

    • 改变

    -Xms40m
    -Xmx512m
    

    -Xms512m
    -Xmx1024m
    
    • 重启Eclipse

    See here

  • 10

    试试这个

    打开 build.gradle 文件

    android {
            dexOptions {
               javaMaxHeapSize = "4g"
            }
       }
    
  • 26

    以下对我有用 . 只需添加以下代码段:

    android {
            compileSdkVersion 25
            buildToolsVersion '25.0.1'
    
    defaultConfig {
            applicationId "yourpackage"
            minSdkVersion 10
            targetSdkVersion 25
            versionCode 1
            versionName "1.0"
            multiDexEnabled true
        }
    dexOptions {
            javaMaxHeapSize "4g"
        }
    }
    
  • 12

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

    dexOptions {
        javaMaxHeapSize "1g"
    }
    

    to(在gradle中添加此行)

    dexOptions {
            javaMaxHeapSize "4g"
        }
    
  • 36

    重新启动我的MacBook为我解决了这个问题 .

  • 187

    您需要在Jdeveloper中增加内存大小,转到 setDomainEnv.cmd .

    set WLS_HOME=%WL_HOME%\server    
    set XMS_SUN_64BIT=**256**
    set XMS_SUN_32BIT=**256**
    set XMX_SUN_64BIT=**3072**
    set XMX_SUN_32BIT=**3072**
    set XMS_JROCKIT_64BIT=**256**
    set XMS_JROCKIT_32BIT=**256**
    set XMX_JROCKIT_64BIT=**1024**
    set XMX_JROCKIT_32BIT=**1024**
    
    if "%JAVA_VENDOR%"=="Sun" (
        set WLS_MEM_ARGS_64BIT=**-Xms256m -Xmx512m**
        set WLS_MEM_ARGS_32BIT=**-Xms256m -Xmx512m**
    ) else (
        set WLS_MEM_ARGS_64BIT=**-Xms512m -Xmx512m**
        set WLS_MEM_ARGS_32BIT=**-Xms512m -Xmx512m**
    )
    

    set MEM_PERM_SIZE_64BIT=-XX:PermSize=**256m**
    set MEM_PERM_SIZE_32BIT=-XX:PermSize=**256m**
    
    if "%JAVA_USE_64BIT%"=="true" (
        set MEM_PERM_SIZE=%MEM_PERM_SIZE_64BIT%
    ) else (
        set MEM_PERM_SIZE=%MEM_PERM_SIZE_32BIT%
    )
    
    set MEM_MAX_PERM_SIZE_64BIT=-XX:MaxPermSize=**1024m**
    set MEM_MAX_PERM_SIZE_32BIT=-XX:MaxPermSize=**1024m**
    
  • -2

    我'm working in Android Studio and encountered this error when trying to generate a signed APK for release. I was able to build and test a debug APK with no problem, but as soon as I wanted to build a release APK, the build process would run for minutes on end and then finally terminate with the 2939397 . I increased the heap sizes for both the VM and the Android DEX compiler, but the problem persisted. Finally, after many hours and mugs of coffee it turned out that the problem was in my app-level ' build.gradle ' file - I had the ' minifyEnabled ' parameter for the release build type set to ' false ', consequently running Proguard stuffs on code that hasn' t已通过代码缩小的过程(见https://developer.android.com/studio/build/shrink-code.html) . 我将'minifyEnabled'参数更改为'true'并且发布版本像梦一样执行:)

    简而言之,我必须从以下位置更改我的应用级“build.gradle”文件:// ...

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            signingConfig signingConfigs.sign_config_release
        }
        debug {
            debuggable true
            signingConfig signingConfigs.sign_config_debug
        }
    }
    
    //...
    

    //...
    
    buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            signingConfig signingConfigs.sign_config_release
        }
        debug {
            debuggable true
            signingConfig signingConfigs.sign_config_debug
        }
    }
    
    //...
    
  • 4

    要在IntelliJ IDEA中增加堆大小,请遵循以下说明 . 它对我有用 .

    对于Windows用户,

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

    idea64.exe.vmoptions
    

    编辑文件并添加以下内容 .

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

    这就对了 !!

  • -1

    在Netbeans中,设计最大堆大小可能会有所帮助 . 转到Run => Set Project Configuration => Customize . 在Run of the popped up窗口中,转到VM Option,填写 -Xms2048m -Xmx2048m . 它可以解决堆大小问题 .

相关问题