王小那个鑫
作者王小那个鑫2023-05-16 15:08
数据库运维工程师, 乐山市商业银行

关于oom:GC overhead limit exceeded问题的分析与疑问

字数 1024阅读 1910评论 4赞 3

一、背景

应用运维人员通过granfna监控软件发现某主机内存在某一时刻内存使用率达到了90%以上,应用系统部分业务收到影响。此时应用人员通过应用日志查看,在异常期间,出现大量的out of memory:GC overhead limit exceeded的错误。找到应用厂商进行分析后,得出结论,告知是我们的应用启动参数maxPermSize设置过小导致(该参数设置大小为1G),需要增加-XX:MaxPermSize的大小。

二、基本概念了解

经过资料查询,在java应用启动参数中通常我们会调整几个参数:-Xms,-Xmx,-XX:PermSize,-XX:MaxPermSize;两组参数中分别代表了堆内存大小限制和非堆内存大小限制;堆内存是运行时数据区域,所有类实例和数组的内存均从此处分配,主要分为年轻代(Young Generation)、老年代(Old Generation);对内存存放的是对象,垃圾收集器就是收集这些对象,然后根据GC算法回收。非堆内存用,属于永久代,也称为方法区,存储程序运行时长期存活的对象,比如类的元数据、方法、常量、属性等。在JDK1.8版本,是以MetaSpace表示永久代;

因此,我认为堆内存较为活跃,会根据应用的使用在堆内存中创建新的对象,而由于堆内存的大小有限(设置了参数进行限制),则会有GC垃圾回收机制对堆内存中的释放对象进行回收,而当Java进程花费98%以上的时间执行GC,但只恢复了不到2%的内存,且该动作连续重复了5次,就会抛出java.lang.OutOfMemoryError:GC overhead limit exceeded错误。简单地说,就是应用程序已经基本耗尽了所有可用内存,GC也无法回收

而非堆内存则相对较为静止,在应用启动初期就会根据应用的需求将class等相关信息加载到该部分内存中。而当我们在进行应用启动的时候则会加载大量的class,如果此时永久代的空间不足,那么可能会出现out of memory:Permgen space的问题。

三、疑问

如果按照堆内存和非堆内存的概念来讲,应用厂商告知我们的结论和处理方式是不是就是不正确的呢?在永久代中,是不是不存在gc的回收?-XX:MaxPermSize的参数增大能解决我们的out of memory:GC overhead limit exceeded错误么?欢迎各位中间件专家大佬以及开发大佬踊跃讨论,帮忙解惑

如果觉得我的文章对您有用,请点赞。您的支持将鼓励我继续创作!

3

添加新评论4 条评论

张东焕张东焕技术总监, IBM官方授权讲师
2023-05-16 21:55
设置java verbose garbage collection = true,收集详细GC信息,用工具分析内存回收情况。进一步可以收集heapdump,用工具分析heap使用情况,具体是什么原因导致OOM。
YuLiminYuLimin资深技术顾问, IBM广州
2023-05-16 17:22
什么版本的JDK? 通常是你的应用占了大量的Heap了,GC怎么回收也回收不了,从而导致CPU狂飙,但是无功而返。 结合CPU占用率,GC日志,以及生成的HeapDump文件进行分析之。
HelloWorDomainHelloWorDomain其它, 保密
2023-05-16 15:29
补充,针对内存的扩容是需要谨慎操作的,因为更好的内存往往会带来更高的GC时间,而FGC带来的word stop time,会影响到业务。
HelloWorDomainHelloWorDomain其它, 保密
2023-05-16 15:18
这个报错指花较时间只回收了很少内存。 一般指heap区,而非永久区,这时候,一般GClog看下内存真实使用情况,必要时结合heapdump分析真实内存使用。

泊涯@王小那个鑫 线程对象没释放,占用new对象内存,可以通过调整jvm强制回收方式处理,也可以把占用内存大对象定位出来关闭回收或者放公共资源池

2023-05-16 18:53

HelloWorDomain@王小那个鑫 共同学习,一起进步

2023-05-16 15:42

王小那个鑫@HelloWorDomain 学习了

2023-05-16 15:38
Ctrl+Enter 发表

本文隶属于专栏

最佳实践
不同的领域,都有先行者,实践者,用他们的最佳实践来加速更多企业的建设项目落地。

作者其他文章

相关文章

相关问题

相关资料

X社区推广