JVM 报 GC Overhead limit exceeded 是什么意思?

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

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

1void GCOverheadChecker::check_gc_overhead_limit(GCOverheadTester* time_overhead, 2 GCOverheadTester* space_overhead, 3 bool is_full_gc, 4 GCCause::Cause gc_cause, 5 SoftRefPolicy* soft_ref_policy) { 6 7 // 忽略显式gc命令,比如System.gc(),或者通过JVMTI命令的gc,或者通过jcmd命令的gc 8 if (GCCause::is_user_requested_gc(gc_cause) || 9 GCCause::is_serviceability_requested_gc(gc_cause)) { 10 return; 11 } 12 13 bool print_gc_overhead_limit_would_be_exceeded = false; 14 if (is_full_gc) { 15 //如果gc时间过长,并且gc回收的空间还是不多 16 //gc时间占用98%以上为gc时间过长,可以通过 -XX:GCTimeLimit= 配置,参考gc_globals.hpp: GCTimeLimit 17 //回收空间小于2%为gc回收空间不多,可以通过 -XX:GCHeapFreeLimit= 配置,参考gc_globals.hpp: GCHeapFreeLimit 18 if (time_overhead->is_exceeded() && space_overhead->is_exceeded()) { 19 _gc_overhead_limit_count++; 20 //如果UseGCOverheadLimit这个状态位为开启 21 //默认情况下,是开启的,可以通过启动参数-XX:-UseGCOverheadLimit关闭,参考:gc_globals.hpp: UseGCOverheadLimit 22 if (UseGCOverheadLimit) { 23 //如果超过规定次数,这个次数默认不可配置,必须开启develop编译jdk才能配置,参考gc_globals.hpp: GCOverheadLimitThreshold 24 if (_gc_overhead_limit_count >= GCOverheadLimitThreshold){ 25 //设置状态位,准备抛出OOM 26 set_gc_overhead_limit_exceeded(true); 27 //清空计数 28 reset_gc_overhead_limit_count(); 29 } else { 30 //如果还没到达次数,但是也快到达的时候,清空所有的软引用 31 bool near_limit = gc_overhead_limit_near(); 32 if (near_limit) { 33 soft_ref_policy->set_should_clear_all_soft_refs(true); 34 log_trace(gc, ergo)("Nearing GC overhead limit, will be clearing all SoftReference"); 35 } 36 } 37 } 38 //需要打印日志,提示GC效率不高 39 print_gc_overhead_limit_would_be_exceeded = true; 40 41 } else { 42 // Did not exceed overhead limits 43 reset_gc_overhead_limit_count(); 44 } 45 } 46 47 if (UseGCOverheadLimit) { 48 if (gc_overhead_limit_exceeded()) { 49 log_trace(gc, ergo)("GC is exceeding overhead limit of " UINTX_FORMAT "%%", GCTimeLimit); 50 reset_gc_overhead_limit_count(); 51 } else if (print_gc_overhead_limit_would_be_exceeded) { 52 assert(_gc_overhead_limit_count > 0, "Should not be printing"); 53 log_trace(gc, ergo)("GC would exceed overhead limit of " UINTX_FORMAT "%% %d consecutive time(s)", 54 GCTimeLimit, _gc_overhead_limit_count); 55 } 56 } 57}

默认配置:gc_globals.hpp

1product(bool, UseGCOverheadLimit, true, \ 2 "Use policy to limit of proportion of time spent in GC " \ 3 "before an OutOfMemory error is thrown") \ 4 \ 5product(uintx, GCTimeLimit, 98, \ 6 "Limit of the proportion of time spent in GC before " \ 7 "an OutOfMemoryError is thrown (used with GCHeapFreeLimit)") \ 8 range(0, 100) \ 9 \ 10product(uintx, GCHeapFreeLimit, 2, \ 11 "Minimum percentage of free space after a full GC before an " \ 12 "OutOfMemoryError is thrown (used with GCTimeLimit)") \ 13 range(0, 100) \ 14 \ 15develop(uintx, GCOverheadLimitThreshold, 5, \ 16 "Number of consecutive collections before gc time limit fires") \ 17 range(1, max_uintx)

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

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

image

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )

JVM 报 GC Overhead limit exceeded 是什么意思? - HelloWorld