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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28051098/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 05:32:04  来源:igfitidea点击:

Tomcat java.lang.OutOfMemoryError: GC overhead limit exceeded

javamultithreadingtomcatgarbage-collection

提问by Uppi

We trying to migrate our application to Tomcat 7.0 from OC4J. The application works fine with OC4J but, in tomcat the performance gets affected when running load testing with 10 users. We get these errors and the application doesnt respond anymore.

我们尝试将我们的应用程序从 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

We tried JAVA_OPTS="-Xms4096m -Xmx8192m. Looks like we still get the error. Please suggest the possible options that we could try..

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

Garbage collection logs

垃圾收集日志

GC invocations=593 (full 539): PSYoungGen total 701120K, used 374720K [0x00000007aaab0000, 0x00000007eaf60000, 0x0000000800000000) eden space 374720K, 100% used [0x00000007aaab0000,0x00000007c18a0000,0x00000007c18a0000) from space 326400K, 0% used [0x00000007d70a0000,0x00000007d70a0000,0x00000007eaf60000) to space 339328K, 0% used [0x00000007c18a0000,0x00000007c18a0000,0x00000007d6400000) ParOldGen total 2796224K, used 2796223K [0x0000000700000000, 0x00000007aaab0000, 0x00000007aaab0000) object space 2796224K, 99% used [0x0000000700000000,0x00000007aaaaffe8,0x00000007aaab0000) PSPermGen total 50688K, used 50628K [0x00000006fae00000, 0x00000006fdf80000, 0x0000000700000000) object space 50688K, 99% used [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]

GC调用= 593(满539):PSYoungGen总701120K,使用374720K [0x00000007aaab0000,0x00000007eaf60000,0x0000000800000000)伊甸空间374720K,使用了100%[0x00000007aaab0000,0x00000007c18a0000,0x00000007c18a0000)从空间326400K,使用0%[0x00000007d70a0000,0x00000007d70a0000,0x00000007eaf60000)到空间339328K,使用0%[0x00000007c18a0000,0x00000007c18a0000,0x00000007d6400000)ParOldGen总2796224K,使用2796223K [0x0000000700000000,0x00000007aaab0000,0x00000007aaab0000)对象空间2796224K,使用[0x0000000700000000,0x00000007aaaaffe8,0x00000007aaab0000)PSPermGen总50688K 99%,使用50628K [0x00000006fae00000, 0x00000006fdf80000,0x0000000700000000)对象空间50688K,使用99%[0x00000006fae00000,0x00000006fdf713a8,0x00000006fdf80000)4482.450:[全GC [PSYoungGen:374720K->339611K(701120K)] [ParOldGen: 2796223K->2796222K(2796224K)] 3170943K->3135834K(3497344K) [PSPermGen: 5056068K-5056028K]2.5(506268K) 8秒]8

采纳答案by John Vint

GC Overrhead Limit exceededusually implies the application is 'leaking' memory some where. Your heap is high in memory use, like 98/99% and a full GC will retrieve maybe a percent or two. What that will do is it will spend most of the time GCing. The JVM checks to see how often it has spent GCing and if it exceeds some limit this error is what is thrown.

GC Overrhead Limit exceeded通常意味着应用程序在某些地方“泄漏”内存。你的堆内存使用率很高,比如 98/99%,一个完整的 GC 可能会检索到一两个百分比。它将做的是它将大部分时间花在GCing上。JVM 检查它花费 GC 的频率,如果它超过某个限制,就会抛出这个错误。

To resolve it you will need to check where the leak is occurring. Do this by getting a heap dump. You can use jmap for that. Once you get it, you should see the % of the heap will probably belong mostly to one set of objects

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

We tried JAVA_OPTS="-Xms4096m -Xmx8192m. Looks like we still get the error. Please suggest the possible options that we could try..

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

That's a lot and only delays the inevitable.

这太多了,只会拖延不可避免的事情。



Edit from you update

从你更新编辑

As I expected your OldGen space is at 99% with little reclaimed. OldGen space is where all long lived object will be placed. Since you are not reclaiming some memory all of those objects will eventually be placed into OldGen and you will run out of memory.

正如我预期的那样,您的 OldGen 空间为 99%,几乎没有回收。OldGen 空间是放置所有长期存在的对象的地方。由于您没有回收一些内存,所有这些对象最终都会被放入 OldGen 中,并且您将耗尽内存。

What's worth reading are the two lines here:

值得一读的是这里的两行:

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) 

Like I mentioned, OldGen is at 99% and a Full GC only reclaims 1KB YounGenand 35KB OldGen. It will have to GC almost immediately again. It should be GCing GBs at this point.

就像我提到的, OldGen 是 99% 并且 Full GC 只回收1KB YoungGen35KB OldGen。它将不得不几乎立即再次进行 GC。此时应该是 GCing GB。

So

所以

Get a heap dump and find out what the greatest offender here is. Investigate where these objects are being created and why they are not becoming unreachable.

获取堆转储并找出最大的违规者是什么。调查创建这些对象的位置以及为什么它们不会变得无法访问。

If you have any other questions about how/where or why let me know, but there is nothing else I can tell you at this point.

如果您对如何/在哪里或为什么有任何其他问题,请告诉我,但此时我无法告诉您其他任何事情。

回答by souser

What is your permsize ? Can you increase it to say 512m

你的许可大小是多少?你能增加它说512m吗

-XX:MaxPermSize=512m

回答by Harsh Maheswari

The detail message "GC overhead limit exceeded" indicates that the garbage collector is running all the time and Java program is making very slow progress.

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

Can be fixed in 2 ways 1) By Suppressing GC Overhead limit warning in JVM parameter Ex--Xms1024M -Xmx2048M -XX:+UseConcMarkSweepGC -XX:-UseGCOverheadLimit

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

-UseGCOverheadLimit- Parameter is used to suppress GCOverHead.

-UseGCOverheadLimit- 参数用于抑制 GCOverHead。

2) By identifying memory leak

2)通过识别内存泄漏