java.lang.OutOfMemoryError: GC overhead limit exceeded

I am getting this error in a program that creates several (hundreds of thousands) HashMap objects with a few (15-20) text entries each. These Strings have all to be collected (without breaking up into smaller amounts) before being submitted to a database.

According to Sun, the error happens "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.".

Apparently, one could use the command line to pass arguments to the JVM for

  • Increasing the heap size, via "-Xmx1024m" (or more), or
  • Disabling the error check altogether, via "-XX:-UseGCOverheadLimit".
  • The first approach works fine, the second ends up in another java.lang.OutOfMemoryError, this time about the heap.

    So, question: is there any programmatic alternative to this, for the particular use case (ie, several small HashMap objects)? If I use the HashMap clear() method, for instance, the problem goes away, but so do the data stored in the HashMap! :-)

    The issue is also discussed in a related topic in StackOverflow.


    You're essentially running out of memory to run the process smoothly. Options that come to mind:

  • Specify more memory like you mentioned, try something in between like -Xmx512m first
  • Work with smaller batches of HashMap objects to process at once if possible
  • If you have a lot of duplicate strings, use String.intern() on them before putting them into the HashMap
  • Use the HashMap(int initialCapacity, float loadFactor) constructor to tune for your case

  • The following worked for me. Just add the following snippet:

    dexOptions {
            javaMaxHeapSize "4g"
    }
    

    To your build.gradle :

    android {
        compileSdkVersion 23
        buildToolsVersion '23.0.1'
    
        defaultConfig {
            applicationId "yourpackage"
            minSdkVersion 14
            targetSdkVersion 23
            versionCode 1
            versionName "1.0"
    
            multiDexEnabled true
        }
    
        buildTypes {
            release {
                minifyEnabled false
                proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            }
        }
    
        packagingOptions {
    
        }
    
        dexOptions {
            javaMaxHeapSize "4g"
        }
    }
    

    @takrl: The default setting for this option is:

    java -XX:+UseConcMarkSweepGC
    

    which means, this option is not active by default. So when you say you used the option " +XX:UseConcMarkSweepGC " I assume you were using this syntax:

    java -XX:+UseConcMarkSweepGC
    

    which means you were explicitly activating this option. For the correct syntax and default settings of Java HotSpot VM Options @ this document

    链接地址: http://www.djcxy.com/p/82950.html

    上一篇: 无法为对象堆预留足够的空间来启动JVM

    下一篇: java.lang.OutOfMemoryError:超出GC开销限制