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

我在一个程序中得到这个错误,该程序创建了几个(数十万个)HashMap对象,每个对象都有几个(15-20)个文本项。 这些字符串在提交到数据库之前都已收集(没有分解成更小的数量)。

据Sun称,错误发生在“如果在垃圾收集中花费了太多时间:如果超过总时间的98%用于垃圾收集,并且小于2%的堆被恢复,则会抛出OutOfMemoryError。 ”。

显然,可以使用命令行将参数传递给JVM

  • 通过“-Xmx1024m”(或更多)或者增加堆大小
  • 完全禁用错误检查,通过“-XX:-UseGCOverheadLimit”。
  • 第一种方法工作正常,第二种方法在另一个java.lang.OutOfMemoryError中结束,这次是关于堆。

    所以,问题:对于这个特定的用例(即几个小型的HashMap对象),是否有任何程序化的替代方案? 例如,如果我使用HashMap clear()方法,问题就会消失,但存储在HashMap中的数据也会消失! :-)

    StackOverflow中的相关主题也讨论了该问题。


    你基本上没有足够的内存来顺利运行这个过程。 想到的选项:

  • 像上面提到的那样指定更多的内存,首先尝试一下像-Xmx512m类的东西
  • 尽可能使用较小批次的HashMap对象进行处理
  • 如果您有很多重复的字符串,请在将它们放入HashMap之前使用它们的String.intern()
  • 使用HashMap(int initialCapacity, float loadFactor)构造函数调整您的情况

  • 以下为我工作。 只需添加以下代码片段即可:

    dexOptions {
            javaMaxHeapSize "4g"
    }
    

    到你的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:这个选项的默认设置是:

    java -XX:+UseConcMarkSweepGC
    

    这意味着,此选项默认情况下不处于活动状态。 所以当你说你使用了“ +XX:UseConcMarkSweepGC ”选项时,我假设你使用的是这种语法:

    java -XX:+UseConcMarkSweepGC
    

    这意味着你明确地激活了这个选项。 有关Java HotSpot VM Options @@本文档的正确语法和默认设置

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

    上一篇: java.lang.OutOfMemoryError: GC overhead limit exceeded

    下一篇: javac junit gives "error: package org.junit does not exist"