温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

如何理解JVM的GC overhead limit exceeded错误

发布时间:2021-10-23 16:23:54 来源:亿速云 阅读:583 作者:柒染 栏目:云计算

如何理解JVM的GC overhead limit exceeded错误,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。

java 中有几个难兄难弟,比如我昨天写的 java.lang.OutOfMemoryError: Java heap space 和今天要写的 java.lang.OutOfMemoryError: GC overhead limit exceeded 等。要搞清这些知识,就需要深入的理解 JVM 底层原理和实现机制。

那么我们今天就具体来说说 java.lang.OutOfMemoryError: GC overhead limit exceeded 吧!

我们都知道,Java 语言的一大优势就是内存管理,也就是垃圾回收机制。相比其他语言,如:C++等,它们这些语言中并没有自动内存回收机制, 需要程序员手工编写代码来进行内存分配和释放, 以重复利用堆内存。

也正是因为 Java 语言有自动垃圾回收机制,所以一些程序员在使用不当的情况下,会发生一系列你意想不到的 OutOfMemoryError。关于 OutOfMemoryError 错误,目前一共有 8 种,我们一一的来搞定它们!

java.lang.OutOfMemoryError: GC overhead limit exceeded 这种情况发生的原因是程序基本上耗尽了所有的可用内存, GC 也清理不了。

更准确的说法应该是:执行垃圾收集的时间比例太大,有效的运算量太小。默认情况下,如果GC花费的时间超过 98%,并且GC 回收的内存少于 2%,JVM 就会抛出这个错误。

如何理解JVM的GC overhead limit exceeded错误

java.lang.OutOfMemoryError: GC overhead limit exceeded 错误只在连续多次 GC 都只回收了不到2%的极端情况下才会抛出。假如不抛出 GC overhead limit 错误会发生什么情况呢? 那就是 GC 清理的这么点内存很快会再次填满,迫使 GC 再次执行。这样就形成恶性循环,CPU 使用率一直是 100%,而 GC 却没有任何成果。系统用户就会看到系统卡死。以前只需要几毫秒的操作,现在需要好几分钟才能完成。

下面我们来看一个产生“GC overhead limit exceeded” 错误的例子:

如何理解JVM的GC overhead limit exceeded错误

为了能够更快的看到效果,我们可以设置一下 JVM 的参数:

如何理解JVM的GC overhead limit exceeded错误

需要注意的是,不同的 GC 算法。产生的错误信息也不相同,有的可能会产生 java.lang.OutOfMemoryError: Java heap space 错误。

关于具体的 GC 算法,我给大家一张关于 Java8 GC 算法的列表,我后面再具体的写文章来讲。

如何理解JVM的GC overhead limit exceeded错误

我们在说说上面产生 OutOfMemoryError 错误的代码吧。Map 在进行 rehash 时抛出了 java.lang.OutOfMemoryError 错误消息。如果使用其他垃圾收集算法,比如 -XX:+UseConcMarkSweepGC,或者 -XX:+UseG1GC,错误将被默认的 exception handler 所捕获,但是没有 stacktrace 信息,因为在创建 Exception 时没办法填充 stacktrace 信息。

再比如,有些厂商的 JVM 在 Win7x64,Java8 环境配置如下 UseG1GC:

如何理解JVM的GC overhead limit exceeded错误

结果产生的错误信息却是:

如何理解JVM的GC overhead limit exceeded错误

上面这些真实的案例表明,在资源受限的情况下,无法准确预测程序会死于哪种具体的原因。所以在这类错误面前,不能绑死某种特定的错误处理顺序。

有的人在解决 “java.lang.OutOfMemoryError: GC overhead limit exceeded” 错误时,配置了下面的启动参数:

我告诉你,这是一种完全错误的做法。因为 UseGCOverheadLimit 这样使用并不能真正地解决问题,只能推迟一点 out of memory 错误发生的时间,到最后还得进行其他处理。指定这个选项,会将原来的 java.lang.OutOfMemoryError: GC overhead limit exceeded 错误掩盖,变成更常见的 java.lang.OutOfMemoryError: Java heap space 错误消息。

有时候触发 GC overhead limit 错误的原因, 是因为分配给JVM的堆内存不足。这种情况下只需要增加堆内存大小即可。

在大多数情况下, 增加堆内存并不能解决问题。例如程序中存在内存泄漏, 增加堆内存只能推迟产生 java.lang.OutOfMemoryError: Java heap space 错误的时间。

看完上述内容,你们掌握如何理解JVM的GC overhead limit exceeded错误的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注亿速云行业资讯频道,感谢各位的阅读!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI