“java.lang.OutOfMemoryError:超出GC开销限制”中的GC时间过长的持续时间 [英] Duration of Excessive GC Time in "java.lang.OutOfMemoryError: GC overhead limit exceeded"

查看:1480
本文介绍了“java.lang.OutOfMemoryError:超出GC开销限制”中的GC时间过长的持续时间的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

偶尔,在每两天一次到每两周一次之间,我的应用程序崩溃在代码中的一个看似随机的位置: java.lang.OutOfMemoryError:超出GC开销限制。如果我谷歌这个错误,我来到这个SO问题,这导致我这块sun文档展开:


如果太多时间是
,并行收集器将会抛出一个OutOfMemoryError被用于垃圾收集:如果超过98%的总时间是垃圾收集中花费的
,并且小于2%的堆被恢复,则
OutOfMemoryError将被抛出。此功能旨在防止
应用程序长时间运行,同时使
很少或没有进展,因为堆太小。如有必要,可以通过在
命令行中添加选项-XX:-UseGCOverheadLimit来禁用此
功能。


这告诉我,我的应用程序显然花费了垃圾回收总时间的98%,只能恢复堆的2%。



但98%时间?应用程序运行整个两周内的98%?最后一毫秒的98%?



我试图确定一个实际解决此问题的最佳方法,而不仅仅是使用 -XX:-UseGCOverheadLimit 但我觉得有必要更好地理解我正在解决的问题。

解决方案


m试图确定一个实际解决这个问题的最佳方法,而不是仅仅使用 -XX:-UseGCOverheadLimit ,但我觉得有必要更好地理解我正在解决的问题。 / p>

好吧,你使用的内存太多 - 从声音来看,可能是因为内存泄漏缓慢。



您可以尝试使用 -Xmx 来增加堆大小,如果这不是内存泄漏但是一个迹象表明你的应用程序实际上需要大量的堆,而且你现在的设置稍微偏低。如果是内存泄漏,这只会推迟不可避免的。



要调查它是否是内存泄漏,请指示VM在OOM上使用 -XX:+ HeapDumpOnOutOfMemoryError 开关,然后分析堆转储以查看是否存在比应该存在的更多的对象。 http://blogs.oracle.com/alanb/entry/heap_dumps_are_back_with 是一个漂亮的好的地方开始。






编辑:在批量式应用程序中询问此问题后的一天内,我自己就会遇到这个问题。这不是由内存泄漏引起的,增加堆大小也没有帮助。我所做的实际上是减少堆大小(从1GB到256MB),以使整个GC更快(尽管更频繁)。 YMMV,但值得一试。



编辑2:并非所有问题都能通过较小的堆解决...下一步是启用 G1垃圾收集器似乎比CMS做得更好。

Occasionally, somewhere between once every 2 days to once every 2 weeks, my application crashes in a seemingly random location in the code with: java.lang.OutOfMemoryError: GC overhead limit exceeded. If I google this error I come to this SO question and that lead me to this piece of sun documentation which expains:

The parallel collector will throw an OutOfMemoryError if too much time is being spent in garbage collection: if more than 98% of the total time is spent in garbage collection and less than 2% of the heap is recovered, an 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.

Which tells me that my application is apparently spending 98% of the total time in garbage collection to recover only 2% of the heap.

But 98% of what time? 98% of the entire two weeks the application has been running? 98% of the last millisecond?

I'm trying to determine a best approach to actually solving this issue rather than just using -XX:-UseGCOverheadLimit but I feel a need to better understand the issue I'm solving.

解决方案

I'm trying to determine a best approach to actually solving this issue rather than just using -XX:-UseGCOverheadLimit but I feel a need to better understand the issue I'm solving.

Well, you're using too much memory - and from the sound of it, it's probably because of a slow memory leak.

You can try increasing the heap size with -Xmx, which would help if this isn't a memory leak but a sign that your app actually needs a lot of heap and the setting you currently have is slightly to low. If it is a memory leak, this'll just postpone the inevitable.

To investigate if it is a memory leak, instruct the VM to dump heap on OOM using the -XX:+HeapDumpOnOutOfMemoryError switch, and then analyze the heap dump to see if there are more objects of some kind than there should be. http://blogs.oracle.com/alanb/entry/heap_dumps_are_back_with is a pretty good place to start.


Edit: As fate would have it, I happened to run into this problem myself just a day after this question was asked, in a batch-style app. This was not caused by a memory leak, and increasing heap size didn't help, either. What I did was actually to decrease heap size (from 1GB to 256MB) to make full GCs faster (though somewhat more frequent). YMMV, but it's worth a shot.

Edit 2: Not all problems solved by smaller heap... next step was enabling the G1 garbage collector which seems to do a better job than CMS.

这篇关于“java.lang.OutOfMemoryError:超出GC开销限制”中的GC时间过长的持续时间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆