默认情况下,并不是等堆内存耗尽,才会报 OutOfMemoryError,而是如果 JVM 觉得 GC 效率不高,也会报这个错误。

那么怎么评价 GC 效率不高呢?来看下源码:

呢?来看下源码gcOverheadChecker.cpp

void GCOverheadChecker::check_gc_overhead_limit(GCOverheadTester* time_overhead,
GCOverheadTester* space_overhead,
bool is_full_gc,
GCCause::Cause gc_cause,
SoftRefPolicy* soft_ref_policy) { // 忽略显式gc命令,比如System.gc(),或者通过JVMTI命令的gc,或者通过jcmd命令的gc
if (GCCause::is_user_requested_gc(gc_cause) ||
GCCause::is_serviceability_requested_gc(gc_cause)) {
return;
} bool print_gc_overhead_limit_would_be_exceeded = false;
if (is_full_gc) {
//如果gc时间过长,并且gc回收的空间还是不多
//gc时间占用98%以上为gc时间过长,可以通过 -XX:GCTimeLimit= 配置,参考gc_globals.hpp: GCTimeLimit
//回收空间小于2%为gc回收空间不多,可以通过 -XX:GCHeapFreeLimit= 配置,参考gc_globals.hpp: GCHeapFreeLimit
if (time_overhead->is_exceeded() && space_overhead->is_exceeded()) {
_gc_overhead_limit_count++;
//如果UseGCOverheadLimit这个状态位为开启
//默认情况下,是开启的,可以通过启动参数-XX:-UseGCOverheadLimit关闭,参考:gc_globals.hpp: UseGCOverheadLimit
if (UseGCOverheadLimit) {
//如果超过规定次数,这个次数默认不可配置,必须开启develop编译jdk才能配置,参考gc_globals.hpp: GCOverheadLimitThreshold
if (_gc_overhead_limit_count >= GCOverheadLimitThreshold){
//设置状态位,准备抛出OOM
set_gc_overhead_limit_exceeded(true);
//清空计数
reset_gc_overhead_limit_count();
} else {
//如果还没到达次数,但是也快到达的时候,清空所有的软引用
bool near_limit = gc_overhead_limit_near();
if (near_limit) {
soft_ref_policy->set_should_clear_all_soft_refs(true);
log_trace(gc, ergo)("Nearing GC overhead limit, will be clearing all SoftReference");
}
}
}
//需要打印日志,提示GC效率不高
print_gc_overhead_limit_would_be_exceeded = true; } else {
// Did not exceed overhead limits
reset_gc_overhead_limit_count();
}
} if (UseGCOverheadLimit) {
if (gc_overhead_limit_exceeded()) {
log_trace(gc, ergo)("GC is exceeding overhead limit of " UINTX_FORMAT "%%", GCTimeLimit);
reset_gc_overhead_limit_count();
} else if (print_gc_overhead_limit_would_be_exceeded) {
assert(_gc_overhead_limit_count > 0, "Should not be printing");
log_trace(gc, ergo)("GC would exceed overhead limit of " UINTX_FORMAT "%% %d consecutive time(s)",
GCTimeLimit, _gc_overhead_limit_count);
}
}
}

默认配置:gc_globals.hpp

product(bool, UseGCOverheadLimit, true,                                   \
"Use policy to limit of proportion of time spent in GC " \
"before an OutOfMemory error is thrown") \
\
product(uintx, GCTimeLimit, 98, \
"Limit of the proportion of time spent in GC before " \
"an OutOfMemoryError is thrown (used with GCHeapFreeLimit)") \
range(0, 100) \
\
product(uintx, GCHeapFreeLimit, 2, \
"Minimum percentage of free space after a full GC before an " \
"OutOfMemoryError is thrown (used with GCTimeLimit)") \
range(0, 100) \
\
develop(uintx, GCOverheadLimitThreshold, 5, \
"Number of consecutive collections before gc time limit fires") \
range(1, max_uintx)

可以总结出:默认情况下,启用了 UseGCOverheadLimit,连续 5 次,碰到 GC 时间占比超过 98%,GC 回收的内存不足 2% 时,会抛出这个异常。

微信搜索“我的编程喵”关注公众号,每日一刷,轻松提升技术,斩获各种offer:

JVM 报 GC Overhead limit exceeded 是什么意思?的更多相关文章

  1. JVM--你常见的jvm 异常有哪些? 代码演示:StackOverflowError , utOfMemoryError: Java heap space , OutOfMemoryError: GC overhead limit exceeded, Direct buffer memory, Unable_to_create_new_native_Thread, Metaspace

    直接上代码: public class Test001 { public static void main(String[] args) { //java.lang.StackOverflowErro ...

  2. eclipse一直报An internal error occurred during: "Building workspace". GC overhead limit exceeded

    最近导入到eclipse里的工程挺大的,每次eclipse启动之后都回update workspace,然后就一直报: An internal error occurred during: " ...

  3. android studio 解析Excel数据格式导入poi-3.17.jar时的一系列报错及处理Failed resolution of: Ljavax/xml/stream/XMLEventFactory,duplicate entry: org/apache/xmlbeans/xml/stream/Location.class,GC overhead limit exceeded

    在org官网下载的poi jar包,导入到studio compile files('libs/poi-3.17.jar') compile files('libs/poi-ooxml-3.17.ja ...

  4. troubleshooting-sqoop mysql导入hive 报:GC overhead limit exceeded

    Halting due to Out Of Memory Error...18/09/13 21:42:17 INFO mapreduce.Job: Task Id : attempt_1536756 ...

  5. oozie: GC overhead limit exceeded 解决方法

    1.异常表现形式 1)  提示信息      Error java.lang.OutOfMemoryError: GC overhead limit exceeded 2)提示出错      Erro ...

  6. java.lang.OutOfMemoryError:GC overhead limit exceeded

    在调测程序时报java.lang.OutOfMemoryError:GC overhead limit exceeded 错误 错误原因:在用程序进行数据切割时报了该错误.由于在本地执行数据切割测试的 ...

  7. Spark 1.4.1中Beeline使用的gc overhead limit exceeded

    最近使用SparkSQL做数据的打平操作,就是把多个表的数据经过关联操作导入到一个表中,这样数据查询的过程中就不需要在多个表中查询了,在数据量大的情况下,这样大大提高了查询效率.   我启动了thri ...

  8. java.lang.OutOfMemoryError GC overhead limit exceeded原因分析及解决方案

    最近一个上线运行良好的项目出现用户无法登录或者执行某个操作时,有卡顿现象.查看了日志,出现了大量的java.lang.OutOfMemoryError: GC overhead limit excee ...

  9. java.lang.OutOfMemoryError:GC overhead limit exceeded填坑心得

    我遇到这样的问题,本地部署时抛出异常java.lang.OutOfMemoryError:GC overhead limit exceeded导致服务起不来,查看日志发现加载了太多资源到内存,本地的性 ...

随机推荐

  1. 知识图谱KnowledgeGraph核心技术培训班 2月03日— 2月06日

  2. 微信小程序 发送模板消息的功能实现

    背景 - 小程序开发的过程中,绝大多数会满足微信支付 - 那么,作为友好交互的体现,自然就会考虑到支付后的消息通知咯 - 所以,我的小程序项目也要求完成这个效果,so.分享一下自己的实现步骤,以方便道 ...

  3. 微信小程序代码上传,审核发布小程序

    1.打开微信开发者工具 管理员扫码 -> 填写好小程序的项目目录.AppID(必须是客户已注册好的AppID).项目名称 2.在app.js中修改id(客户登录后台管理系统的id),app.js ...

  4. apk开发环境!多亏这份《秋招+金九银十-腾讯面试题合集》跳槽薪资翻倍!再不刷题就晚了!

    开头 最近很多网友反馈:自己从各处弄来的资料,过于杂乱.零散.碎片化,看得时候觉得挺有用的,但过个半天,啥都记不起来了.其实,这就是缺少系统化学习的后果. 为了提高大家的学习效率,帮大家能快速掌握An ...

  5. Xamarin.Forms: 无限滚动的ListView(懒加载方式)

    说明 在本博客中,学习如何在Xamarin.Forms应用程序中设计一个可扩展的无限滚动的ListView.这个无限滚动函数在默认的Xamarin.Forms不存在,因此我们需要为此添加插件.在这里我 ...

  6. win api 窗口操作-窗口置顶与寻找与激活

    https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setwindowpos https://docs.micr ...

  7. apache httpclient 4 范例

    下面是一个通过apache httpclient 4 实现http/https的普通访问和BasicAuth认证访问的例子.依赖的第三方库为: 下面是具体实现: package test; impor ...

  8. Linux centos7编译源码安装redis

    1.安装准备 ① 由于redis底层用c语言编写的,安装redis需要先将官网下载的源码进行编译,编译依赖make和gcc环境,如果没有则需要安装(一般系统中已经装了了make和gcc,无须再装) 安 ...

  9. scrapy爬虫 简单入门

    1. 使用cmd+R命令进入命令行窗口,并进入你需要创建项目的目录 cd 项目地址 2. 创建项目 scrapy startproject <项目名> cd <项目名> 例如 ...

  10. requestAnimationFrame小结

    背景 在Web应用中,实现动画效果的方法比较多,Javascript 中可以通过定时器 setTimeout或者setInterval 来实现,css3 可以使用 transition 和 anima ...