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

心不动则不痛 提交于 2020-03-16 19:23:45

某厂面试归来,发现自己落伍了!>>>

我在一个程序中创建了这个错误,该程序创建了几个(数十万)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来禁用此功能。

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!