默认情况下,并不是等堆内存耗尽,才会报 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. java.io.IOException: Could not find resource com/xxx/xxxMapper.xml

    java.io.IOException: Could not find resource com/xxx/xxxMapper.xml 报错内容: org.apache.ibatis.exception ...

  2. vfd-cloud——一个适合练习上手的云存储网盘springboot项目(开发中)

    vfd-cloud           ​ 一个基于SpringBoot的云存储网盘项目,适合练手学习SpringBoot,用到的技术栈列到了下面.支持用户的注册登陆及修改密码,利用邮箱进行验证.支持 ...

  3. Slack 的想法很好啊,很有创新,牛。

    [原]https://www.leiphone.com/news/201411/aXHUpe4ZFI2sSwpb.html 由于以往一些用于办公的应用反响平平,因此对迅速崛起的办公交流应用Slack, ...

  4. 【Python网络编程】epoll用法

    epoll发展进程 此处添加一下select.poll历程及其优缺点 原理 使用步骤 Create an epoll object--创建1个epoll对象 Tell the epoll object ...

  5. 配置《Orange's一个操作系统的实现》环境心得

    <Orange>这本书开篇第一章就做了一个实例,编写了一段引导扇区的代码,但是引导介质仍然采用了已被淘汰多年的软盘.在经历了两天的痛苦查找后终于找到了最方便的解决办法,在此做一下记录,希望 ...

  6. 单点登录(SSO)的设计与实现

    一.前言 1.SSO说明 SSO英文全称Single Sign On,单点登录.SSO是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统.https://baike.baidu.c ...

  7. LOJ10132

    在 Adera 的异时空中有一张地图.这张地图上有 N 个点,有 N-1 条双向边把它们连通起来.起初地图上没有任何异象石,在接下来的 M 个时刻中,每个时刻会发生以下三种类型的事件之一: 地图的某个 ...

  8. BootstrapValidator验证规则、BootStrap表格:列参数

    BootstrapValidator验证规则 需引用组件 <script src="~/Scripts/jquery-1.10.2.js"></script> ...

  9. 安装Archlinux+UEFI启动

    为了安装Arch自己也走了很多弯路,找了很多教程,最后探索出了这样一个安装方法,不一定适用于每个人. ArchWiki官方安装手册 本方法全程插上网线. 准备 获取镜像 镜像可以从官网获取,访问官方下 ...

  10. Linux下部署tp5项目如何隐藏URL中index.php

    找到nginx配置文件,加入以下代码: location / { if (!-e $request_filename){ rewrite ^/(.*)$ /index.php?s=/$1 last; ...