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

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

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

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

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

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

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


当前回答

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

其他回答

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

如果出现错误:

"内部编译器错误:java.lang.OutOfMemoryError: GC开销限制超过java.lang.AbstractStringBuilder"

将java堆空间增加到2GB,即-Xmx2g。

为此使用下面的代码在你的应用程序gradle文件下的android关闭。

dexOptions { javaMaxHeapSize “4g” }

使用概要工具(如eclipse MAT或VisualVM)修复应用程序中的内存泄漏

使用JDK 1.7。x或更高版本,使用G1GC,它在垃圾收集上花费10%,而不像其他GC算法花费2%。

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

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

请参阅oracle的文章,对这些参数进行微调。

关于SE中G1GC的一些问题:

G1上的Java 7 (JDK 7)垃圾收集和文档

生产环境中的Java G1垃圾收集

积极的垃圾回收策略

The parallel collector will throw an OutOfMemoryError if too much time is being spent in garbage collection. In particular, if more than 98% of the total time is spent in garbage collection and less than 2% of the heap is recovered, OutOfMemoryError will be thrown. This feature is designed to prevent applications from running for an extended period of time while making little or no progress because the heap is too small. If necessary, this feature can be disabled by adding the option -XX:-UseGCOverheadLimit to the command line.