我在一个程序中得到这个错误,该程序创建了几个(数十万)HashMap对象,每个对象有几个(15-20)文本条目。在将这些字符串提交到数据库之前,必须收集所有这些字符串(而不将其分解为更小的数量)。

根据Sun的说法,错误发生在“如果在垃圾收集上花费了太多的时间:如果超过98%的总时间花在垃圾收集上,而不到2%的堆被恢复,则会抛出OutOfMemoryError”。

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

增加堆的大小,通过“-Xmx1024m”(或更多),或者 通过"-XX:-UseGCOverheadLimit"完全禁用错误检查。

第一种方法工作得很好,第二种方法在另一个java.lang中结束。OutOfMemoryError,这次是关于堆的。

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

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


当前回答

如果你有java8,你可以使用G1垃圾收集器,然后运行你的应用程序:

 -XX:+UseG1GC -XX:+UseStringDeduplication

这告诉G1寻找相似的字符串,并在内存中只保留其中一个字符串,其他字符串在内存中只是指向该字符串的指针。

当你有很多重复的字符串时,这很有用。此解决方案可能有效,也可能无效,这取决于每个应用程序。

更多信息: https://blog.codecentric.de/en/2014/08/string-deduplication-new-feature-java-8-update-20-2/ http://java-performance.info/java-string-deduplication/

其他回答

你需要在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
)
and

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

如果您正在创建数十万个哈希映射,那么您使用的哈希映射可能远远超过实际需要;除非处理大文件或图形,否则存储简单数据不应超过Java内存限制。

你应该重新考虑一下你的算法。在这种情况下,我会在这个问题上提供更多的帮助,但在你提供更多关于问题背景的信息之前,我不能提供任何信息。

这帮助我摆脱了这个错误。此选项将禁用 - xx: + DisableExplicitGC

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

dexOptions {
        javaMaxHeapSize "4g"
}

到你的建筑。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"
    }
}

使用替代HashMap实现(Trove)。标准Java HashMap有12倍的内存开销。 你可以在这里阅读细节。