最近线上系统(JDK1.7)出现了多次FullGC,但是情况都不一样,今天有时间,将FullGC的排查思路以及如何解决记录下,供大家一起探讨。

场景一:

系统发布上线之后,里面收到如下告警信息:

内容:计算周期:2019-11-15 00:16:00-18:00,节点:*.*.*.*,FullGC次数:63次(大于阈值:10次),已触发严重告警!

收到上述告警信息之后,第一反应就是代码新发布的功能有问题;但是由于当天发布功能有点多,一时半会无法定位到是哪个功能引起的,因此从功能点排查引起FullGC有点难度;

换个角度,既然发生了FullGC,无外乎几种情况:

  1. 代码中显示调用System.gc();
  2. jvm的堆空间不足
  3. jvm的永久代空间不足

依据上述内容,先按照关键字gc()排查代码,发现代码中存在一个批量导出的功能,在for循环中每次都有显示调用,通过功能验证,发现每次代码执行到这里时都会收到告警信息;同时再次排查每次FullGC时jvm堆变换情况:

通过JVM内存使用情况可以确认,本次FullGC,PermGen、OldGen回收效率均为0%,说明虽然触发了FullGC但是由于并未到达上述2/3两种原因,因此可以再次确认是由于代码中显示调用System.gc引起的,在把代码注释掉之后再次验证,未出现FllGC情况;

场景二:

场景一问题解决之后,过了2天,系统突然间又发生类似的情况,再次排查代码,发现系统中所有gc()关键字均没有了,此时无法确认问题原因。

为了明确该问题的原因,从服务器上导出gc的详细日志

2019-11-26T17:04:52.849+0800: 669022.072: [Full GC (System.gc()) 580M->409M(4096M), 1.2260290 s

通过日志分析,发生FullGC的时候,依然是由于System.gc()导致的,但是代码中却没有,因此还需要分析所有请求,通过告警信息发现,所有告警均出现在2分钟之内,因此可以断定应该是跟某个功能相关,因此按照时间节点过滤这2分钟内容所有请求,通过对比发现,所有发生异常情况下均有一个业务请求在执行,通过代码分析发现这个请求是一个excel导入请求,为了明确此次fullGC的根本原因,需要导出javacore(线程快照)

通过分析快照日志发现:

线程中存在System.gc()方法,通过代码查看,在excel导入过程中使用了jxl组件,该组件中存在两个方法

上述两处均存在现实调用System.gc(),虽然有gcDisabled属性控制,但是通过代码排查发现未设置该属性,某人为false,因此只要使用到上述两个方法,均会触发FllGC。

因此建议不要在使用jxl组件,改为poi组件,或者在使用jxl组件时显示设置gcDisabled属性即可。

场景三:

该场景跟上述都不一样,在系统运行一段时间之后,突然短时间内发生接口出现严重超时的情况,此时通过监控系统查看jvm堆情况,

发现OldGen已经快满了,因而触发FullGC,但是定位是由于什么触发GC,还是花费了一番功夫。

还是从日志下手,在出现FullGC的时候,发现在jvm中存在大量

org.apache.xmlbeans.impl.store.Xobj$AttrXobj
org.apache.xmlbeans.impl.store.Xobj$ElementXobj

说明,系统中大概率存在操作poi,因此迅速排查poi关键字,逐个方法排查(问题发生已经超过2小时还未定位到到问题,此时心里已经是万分着急,但是再着急也需要平和心态,从已经日志和现象中逐一查找,不能随意猜测,此时的任何猜测均会引导你进入另一个歧途),发现在一个批量导入的场景中,存在如下代码:

上述代码的本意是将excel中的所有空行过滤掉,对于一个正常的excel是没有任何问题,但是如果是这样的一个excel文件,就可能会出现问题:

通过图中可以发现,该excel居然被创造出了100w行的空行,虽然通过上面的空过滤可以将这100w行过滤掉,但是不可忽视的是我们会创造近100w个Row对象,且这些对象在短时间内不能被垃圾回收,当程序执行完毕后,由于对象过大就会触发FullGC,导致发生Stop World,因此此时当前jvm的其他服务也会出现大量超时。

因此在处理excel的时候,务必先判断总行数、总大小,在做明细判断。

通过上述三个FullGC的处理场景,发现在发生FullGC的时候,大概率是跟我们代码编写有关,因此如何能够熟练使用各种java命令、以及日志分析,对我们能够快速定位问题是很有帮助的。

同时此处在跟大家分享一个个人心得:所有问题排查均需要建立在对业务十分熟悉的情况下,否则将会走很多弯路,因此建议大家不要单纯盲目迷恋技术,业务+技术才是我们立足的资本。

FullGC排查心得的更多相关文章

  1. 一次性搞清楚线上CPU100%,频繁FullGC排查套路

    “ 处理过线上问题的同学基本上都会遇到系统突然运行缓慢,CPU 100%,以及 Full GC 次数过多的问题. 当然,这些问题最终导致的直观现象就是系统运行缓慢,并且有大量的报警. 本文主要针对系统 ...

  2. 服务器CPU很高,频繁FullGC排查小总结

    可以分为如下步骤: ①通过 top 命令查看 CPU 情况,如果 CPU 比较高,则通过 top -Hp 命令查看当前进程的各个线程运行情况. 找出 CPU 过高的线程之后,将其线程 id 转换为十六 ...

  3. 一点解决版本冲突的应急思路、怎样在所有jar包文件中搜索冲突的方法?

    maven是一个很好的项目管理工具,你可以轻松的定义一个引用,从而达到使用别人写好的库的作用.且maven可以轻松地和jenkins配合,从而使打包部署变得更容易. 但是也因为这样,我们变得更傻瓜了, ...

  4. 转载:51cto 2019好文精选

    转载地址:https://news.51cto.com/art/202001/609544.htm 01.知识科普 傻瓜都能看懂,30张图彻底理解红黑树! TCP三次握手,四次挥手,你真的懂吗? 面试 ...

  5. 关于GC(上):Apache的POI组件导致线上频繁FullGC问题排查及处理全过程

    某线上应用在进行查询结果导出Excel时,大概率出现持续的FullGC.解决这个问题时,记录了一下整个的流程,也可以作为一般性的FullGC问题排查指导. 1. 生成dump文件 为了定位FullGC ...

  6. 记一次线上频繁fullGc的排查解决过程

    发生背景 最近上线的一个项目几乎全是查询业务,并且都是大表的慢查询,sql优化是做了一轮又一轮,前几天用户反馈页面加载过慢还时不时的会timeout,但是我们把对应的sql都优化一遍过后,前台响应还是 ...

  7. 我的MYSQL学习心得(十三) 权限管理

    我的MYSQL学习心得(十三) 权限管理 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) ...

  8. 我的MYSQL学习心得(十七) 复制

    我的MYSQL学习心得(十七) 复制 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据 ...

  9. JDBC驱动自身问题引发的FullGC

    公众号HelloJava刊出一篇<MySQL Statement cancellation timer 故障排查分享>,作者的某服务的线上机器报 502(502是 nginx 做后端健康检 ...

随机推荐

  1. Navicate12激活教程(完整详细版)

    写在前面 最近身边的小伙伴苦于没有Navicat12的激活工具,不能使用最新版的Navicat,鉴于此,遂将自己整理的文章贴出来,供大家参考,不过个人还是主张维护正版的意愿,如果经济实力允许的话,还是 ...

  2. Flutter学习笔记--Dart基础

    前言 Flutter使用Dart语言开发, Dart是面向对象编程语言, 由Google2011年推出, 目前最新版本是2.4.0. 工欲善其事,必先利其器. 为了更好的开发Flutter应用, 我们 ...

  3. Vue中Form表单验证无法消除验证问题

    iView的表单api给出了一个resetFields方法,用于重置整个表单输入的内容并清除验证提示. 但是有时候需要只消除部分的iview的resetFields方法源码是这样的resetField ...

  4. 在虚拟机上的关于Apache(阿帕奇)(3)基于IP访问网站

    这篇随笔是基于IP访问网站,和后面两篇文章基于域名和基于端口一起练习效果更好 基于IP(记得下载httpd服务) 首先使用nmtui命令为网卡添加多个ip地址  输入命令:nmtui  进入下面这个界 ...

  5. 暑期集训20190725 加法(add)

    [题目描述] 数学课,黑板上写着n个数字,记为A1到An,fateice会重复以下操作若干次: 1. 选择两个奇偶性相同的整数Ai和Aj, 将他们擦去 2. 将Ai+Aj写在黑板上 问黑板上最终是否有 ...

  6. 【并发编程】ThreadLocal其实很简单

    什么是ThreadLocal ThreadLocal有点类似于Map类型的数据变量.ThreadLocal类型的变量每个线程都有自己的一个副本,某个线程对这个变量的修改不会影响其他线程副本的值.需要注 ...

  7. Project Euler 58: Spiral primes

    从一开始按以下方式逆时针旋转,可以形成一个边长为七的正方形螺旋: 一个有趣的现象是右下对角线上都有一个奇完全平方数,但是更有趣的是两条对角线上的十三个数中有八个数是素数(已经标红),也就是说素数占比为 ...

  8. printf的实现原理

    printf的声明    int _cdecl printf(const char* format, …);    _cdecl是C和C++程序的缺省调用方式 _CDEDL调用约定:    1.参数从 ...

  9. 2019年10月13日 计算机英语习题 wangqingchao

    Match the explanations in Column B with words and expressions in Columna. (搭配每组中意义相同的词或短语) Types of ...

  10. PHP failed to ptrace(PEEKDATA) pid 13659: Input/output error错误解决方法

    PHP failed to ptrace(PEEKDATA) pid 13659: Input/output error错误解决方法 现在改linux内核文件打开限制<pre>ulimit ...