我们尝试将应用程序从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秒]
答案 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