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

Upp*_*ppi 3 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
Run Code Online (Sandbox Code Playgroud)

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

垃圾收集日志

GC调用= 593(完整539):PSYoungGen总计701120K,使用374720K [0x00000007aaab0000,0x00000007eaf60000,0x0000000800000000] eden space 374720K,100%使用[0x00000007aaab0000,0x00000007c18a0000,0x00000007c18a0000]来自空间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 secs]

Joh*_*int 8

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) 
Run Code Online (Sandbox Code Playgroud)

就像我提到的那样,OldGen是99%而Full GC只收回1KB YounGen35KB OldGen.几乎立刻就要GC了.此时应该是GCing GB.

所以

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

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