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

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

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

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

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

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

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


当前回答

如果出现错误:

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

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

其他回答

嗯……你需要:

Completely rethink your algorithm & data-structures, such that it doesn't need all these little HashMaps. Create a facade which allows you page those HashMaps in-and-out of memory as required. A simple LRU-cache might be just the ticket. Up the memory available to the JVM. If necessary, even purchasing more RAM might be the quickest, CHEAPEST solution, if you have the management of the machine that hosts this beast. Having said that: I'm generally not a fan of the "throw more hardware at it" solutions, especially if an alternative algorithmic solution can be thought up within a reasonable timeframe. If you keep throwing more hardware at every one of these problems you soon run into the law of diminishing returns.

你到底想做什么?我怀疑有更好的方法来解决你的实际问题。

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

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

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

dexOptions { javaMaxHeapSize “4g” }

您实际上正在耗尽内存,无法顺利运行进程。想到的选项有:

像你提到的那样指定更多的内存,首先尝试介于两者之间的内存,比如-Xmx512m 如果可能,使用更小批量的HashMap对象一次性处理 如果你有很多重复的字符串,在将它们放入HashMap之前,对它们使用String.intern() 使用HashMap(int initialCapacity, float loadFactor)构造函数针对您的情况进行调优

@takrl:默认设置为:

java -XX:+UseConcMarkSweepGC

这意味着,默认情况下,该选项不是活动的。所以当你说你使用了期权 “+ XX: UseConcMarkSweepGC” 我假设你使用的是这样的语法:

java -XX:+UseConcMarkSweepGC

也就是说你明确地激活了这个选项。 为正确的语法和Java热点虚拟机选项的默认设置@此 文档