java.lang.OutOfMemoryError:GC overhead limit exceeded
你好,我是看山。
java.lang.OutOfMemoryError
这个错误是比较经典的错误了,经过 JDK 不断的迭代,服务器硬件的不断升级。。。总之,社会在发展,时代在进步。很多错误已经消失在时代的浪潮中。我也是很久没有见过这个错误了,以至于都以为在 Java 的世界中不会再碰到这个错误。结果,就在最疏忽的时候碰到了 TA,真是,心中一万只神兽奔袭而过,狠狠的践踏了我这颗上了年纪的心脏啊。
吐槽完毕,言归正传。
Java 刚刚出现的年代,有一个相比于其他语言的优势就是,内存回收机制。不需要明确的调用释放内存的 API,java 就自动完成,这个过程就是 Garbage Collection,简称 GC。这对以懒著称的程序猿们来说,绝对是重大利好。但是,凡事有利必有弊,可以肯定的是,Java 语言是人创造的,GC 也是人编写的代码,绝对不是机器自动完成的。也就是说,GC 的过程是另外一群程序猿根据可能出现的情况,预设了 GC 条件,把符合回收条件的内存空间释放出来。一旦被占用的内存空间不符合释放的条件,GC 没办法清理,那就会适时出现java.lang.OutOfMemoryError
。这个错误就是提醒我们这群程序猿,写 GC 程序的程序猿不知道这种情况怎么处理,为了安全也不便处理,谁使用 Java 就自己看着解决吧。
说起来,java.lang.OutOfMemoryError
有几种分类的,这次碰到的是java.lang.OutOfMemoryError: GC overhead limit exceeded
,下面就来说说这种类型的内存溢出。
简单来说,java.lang.OutOfMemoryError: GC overhead limit exceeded
发生的原因是,当前已经没有可用内存,经过多次 GC 之后仍然没能有效释放内存。
1. 原因
众所周知,JVM 的 GC 过程会因为 STW,只不过停顿短到不容易感知。当引起停顿时间的 98%都是在进行 GC,但是结果只能得到小于 2%的堆内存恢复时,就会抛出java.lang.OutOfMemoryError: GC overhead limit exceeded
这个错误。Plumbr给出一个示意图:
这个错误其实就是空闲内存与 GC 之间平衡的一个限制,当经过几次 GC 之后,只有少于 2%的内存被释放,也就是很少的空闲内存,可能会再次被快速填充,这样就会触发再一次的 GC。这就是一个恶性循环了,CPU 大部分的时间在做 GC 操作,没有时间做具体的业务操作,可能几毫秒的任务需要几分钟都无法完成,整个应用程序就形同虚设了。
2. 示例
从Plumbr上找的一个例子,这里直接给出。
然后设定堆内存是 100m,比如java -Xmx100m -XX:+UseParallelGC Wrapper
。不同的系统环境可能需要设置不同的堆内存大小,否则会产生不同的 OOM 错误。其实也算是好理解,因为java.lang.OutOfMemoryError: GC overhead limit exceeded
需要有两个条件:98%的时间和 2%的内存。如果这两个条件有一个没有达到,结果 Map 对象扩容,那就可能出现java.lang.OutOfMemoryError: Java heap space
这个错误。
3. 解决方法
3.1 JVM 参数
JVM 给出一个参数避免这个错误:-XX:-UseGCOverheadLimit
。
但是,这个参数并不是解决了内存不足的问题,只是将错误发生时间延后,并且替换成java.lang.OutOfMemoryError: Java heap space
。
3.2 堆内存
还有一个偷懒的方法是:增大堆内存。既然堆内存少了,那就增加堆内存即可。
但是,这个方法也不是万能的。因为程序里可能有内存泄露。这个时候即使再增大堆内存,也会有用完的时候。
所以前两个方法都只是治标不治本而已。
3.3 终极方法
其实还是有一个终极方法的,而且是治标治本的方法,就是找到占用内存大的地方,把代码优化了,就不会出现这个问题了。
怎么找到需要优化的代码呢?就是通过 heap dump 生产 jvm 快照,通过分析快照找到占用内存大的对象,从而找到代码位置。
通过设置-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=heapdump
参数来生产快照,然后通过 VisualVM 或者MAT等工具分析快照内容进行定位。通过这个参数是将发生 OOM 时的堆内存所有信息写入快照文件,也就是说,如果此时堆内存中有敏感信息的话,那就可能造成信息泄漏了。
你好,我是看山。游于码界,戏享人生。如果文章对您有帮助,请点赞、收藏、关注。我还整理了一些精品学习资料,关注公众号「看山的小屋」,回复“资料”即可获得。
👇🏻欢迎关注个人公众号,领取精选资料👇🏻
版权声明: 本文为 InfoQ 作者【看山】的原创文章。
原文链接:【http://xie.infoq.cn/article/1d86243198c38c4eaf2cb36c1】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。
评论