我在一个程序中创建了这个错误,该程序创建了几个(数十万)HashMap对象,每个对象都有几个(15-20)文本条目。 这些字符串必须全部收集(不分解成较小的数量),然后再提交给数据库。
根据Sun的说法,该错误发生“如果在垃圾回收上花费了太多时间:如果在垃圾回收上花费了总时间的98%以上,而回收不到2%的堆,则将引发OutOfMemoryError。 ”。
显然,可以使用命令行将参数传递给JVM
- 通过“ -Xmx1024m”(或更多)增加堆大小,或
- 通过“ -XX:-UseGCOverheadLimit”完全禁用错误检查。
第一种方法可以很好地工作,第二种方法最后是另一个java.lang.OutOfMemoryError,这是关于堆的。
因此,问题是:对于特定的用例(例如,几个小的HashMap对象),是否有任何编程替代方法? 例如,如果我使用HashMap clear()方法,问题就会消失,但是存储在HashMap中的数据也会消失! :-)
StackOverflow的相关主题中也讨论了此问题。
#1楼
这帮助我摆脱了这个错误。此选项禁用-XX:+ DisableExplicitGC
#2楼
使用替代的HashMap实现( Trove )。 标准Java HashMap具有大于12倍的内存开销。 人们可以在这里阅读详细信息。
#3楼
如果发生错误:
“内部编译器错误:java.lang.OutOfMemoryError:java.lang.AbstractStringBuilder超出了GC开销限制”
将Java堆空间增加到2GB,即-Xmx2g.
#4楼
在等待结束时不要将整个结构存储在内存中。
将中间结果而不是哈希表写入数据库中的临时表-从功能上讲,数据库表等效于哈希表,即两者均支持对数据的键控访问,但该表不受内存限制,因此请在此处使用索引表,而不要使用索引表哈希图。
如果正确完成,您的算法甚至都不会注意到更改-此处正确意味着意味着使用一个类来表示表,甚至像哈希表一样为它提供put(key,value)和get(key)方法。
中间表完成后,从中而不是从内存中生成所需的sql语句。
#5楼
如果在垃圾回收上花费了太多时间,则并行收集器将抛出OutOfMemoryError
。 特别是,如果在垃圾回收上花费了总时间的98%以上,而回收不到2%的堆,则会抛出OutOfMemoryError
。 此功能旨在防止应用程序长时间运行,而由于堆太小而几乎没有进展,甚至没有进展。 如有必要,可以通过在命令行中添加选项-XX:-UseGCOverheadLimit
来禁用此功能。
来源:oschina
链接:https://my.oschina.net/u/3797416/blog/3196124