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

时间:2015-01-20 17:03:38

标签: java multithreading tomcat garbage-collection

我们尝试将应用程序从OC4J迁移到Tomcat 7.0。该应用程序适用于OC4J,但在tomcat中,当运行10个用户的负载测试时,性能会受到影响。我们收到这些错误,应用程序不再响应。

---java.lang.OutOfMemoryError: GC overhead limit exceeded 

Exception in thread "ajp-bio-8009-exec-231" java.lang.OutOfMemoryError: GC overhead limit exceeded 
Exception in thread "ContainerBackgroundProcessor[StandardEngine[Catalina]]" java.lang.OutOfMemoryError: GC overhead limit exceeded 

Exception in thread "ajp-bio-8009-exec-236" java.lang.OutOfMemoryError: GC overhead limit exceeded 
Exception in thread "ajp-bio-8009-exec-208" java.lang.OutOfMemoryError: GC overhead limit exceeded 
java.lang.OutOfMemoryError: GC overhead limit exceeded 

java.lang.OutOfMemoryError: GC overhead limit exceeded 

Exception in thread "Thread-33" java.lang.OutOfMemoryError: GC overhead limit exceeded 

Exception in thread "ajp-bio-8009-exec-258" java.lang.OutOfMemoryError: GC overhead limit exceeded 

java.lang.OutOfMemoryError: GC overhead limit exceeded

我们尝试了JAVA_OPTS="-Xms4096m -Xmx8192m。看起来我们仍然得到错误。请建议我们可以尝试的选项..

垃圾收集日志

GC调用= 593(完整539):  PSYoungGen总计701120K,使用374720K [0x00000007aaab0000,0x00000007eaf60000,0x0000000800000000)   伊甸园空间374720K,100%使用[0x00000007aaab0000,0x00000007c18a0000,0x00000007c18a0000)   来自space 326400K,0%使用[0x00000007d70a0000,0x00000007d70a0000,0x00000007eaf60000)   到空间339328K,使用0%[0x00000007c18a0000,0x00000007c18a0000,0x00000007d6400000)  ParOldGen总计2796224K,使用2796223K [0x0000000700000000,0x00000007aaab0000,0x00000007aaab0000)   对象空间2796224K,99%使用[0x0000000700000000,0x00000007aaaaffe8,0x00000007aaab0000)  PSPermGen总计50688K,使用50628K [0x00000006fae00000,0x00000006fdf80000,0x0000000700000000)   对象空间50688K,99%使用[0x00000006fae00000,0x00000006fdf713a8,0x00000006fdf80000) 4482.450:[Full GC [PSYoungGen:374720K-> 339611K(701120K)] [ParOldGen:2796223K-> 2796222K(2796224K)] 3170943K-> 3135834K(3497344K)[PSPermGen:50628K-> 50628K(50688K)], 1.4852620秒]

3 个答案:

答案 0 :(得分:6)

GC Overrhead Limit exceeded通常意味着应用程序正在泄漏'记忆一些地方。你的堆内存使用率很高,比如98/99%,一个完整的GC可以检索一两个百分点。它将做的是它将花费大部分时间GCing。 JVM检查它是否经常使用GCing,如果它超过某个限制,则会抛出此错误。

要解决此问题,您需要检查泄漏发生的位置。通过获取堆转储来执行此操作。你可以使用jmap。一旦你得到它,你应该看到堆的百分比可能主要属于一组对象

  

我们尝试了JAVA_OPTS =" -Xms4096m -Xmx8192m。看起来我们仍然得到错误。请建议我们可以尝试的选项..

这很多,只会延迟不可避免的事情。


从您更新

进行编辑

正如我所料,你的OldGen空间为99%,几乎没有回收。 OldGen空间是放置所有长寿命对象的地方。由于你没有回收一些内存,所有这些对象最终会被放入OldGen,你将耗尽内存。

值得一读的是这两行:

ParOldGen total 2796224K, used 2796223K [0x0000000700000000, 0x00000007aaab0000, 0x00000007aaab0000) object space 2796224K, 99% 

Full GC [PSYoungGen: 374720K->339611K(701120K)] [ParOldGen: 2796223K->2796222K(2796224K)] 3170943K->3135834K(3497344K) 

正如我所提到的,OldGen为99%而Full GC仅回收 1KB YounGen 35KB OldGen 。几乎立刻就要GC了。此时应该是GCing GB。

因此

获取堆转储并找出这里最伟大的罪犯是什么。调查这些对象的创建位置以及它们无法到达的原因。

如果您对如何/在何处或为何让我知道有任何其他问题,但此时我无法告诉您。

答案 1 :(得分:1)

详细消息“超出GC开销限制”表示垃圾收集器一直在运行,Java程序进展非常缓慢。

可以通过2种方式修复  1)通过抑制JVM参数中的GC开销限制警告      前 - -Xms1024M -Xmx2048M -XX:+ UseConcMarkSweepGC -XX:-UseGCOverheadLimit

-UseGCOverheadLimit - 参数用于抑制GCOverHead。

2)通过识别内存泄漏

答案 2 :(得分:-1)

你的permsize是什么?你可以把它增加到512米

-XX:MaxPermSize=512m