技术侦探日记 01 - FULL GC篇

引言

众里寻他千百度,蓦然回首,还是垃圾回收;内存占用过高,cpu负载居高不下,如何高效的借助工具来排查问题,让我们跟随本文来抽丝剥茧,让头疼的垃圾回收和full gc问题浮出水面...
上周四微信上收到智能告警,某应用出现full gc频繁问题,初步观察了下sgm和线上机器情况,定位问题。每次告警都是对我们每个金融消防员的考验:如履薄冰,胆战心惊。

报 警

image

立 案 调 查

  • 分析依据:发生fullGC的最常见情况是老年代或者永久代空间不足时。

  • 现场分析:通过SGM查看老年代和永久代的空间占比剩余空间还有一定比例,不至于发生fullGC,发生原因最后分析。

image

另外sgm上看了下jvm监控,发现堆内存从14号上午窜上去后再没下来过,下面这个图很容易定位是发生了内存泄漏,以下的思路就顺着定位内存泄漏的程序进行

image
  • 排查:看了下mapi代码提交记录,近期无上线,初步排除新上线代码问题。
image

在sure上使用jmap命令,发现char占据大量内存,怀疑存在大字符串。

image

周五找运维下了一份详细的dump文件,使用亮哥之前分享过的IBMHeapAnalyzer工具,分析发现问题可能出在EnterRealNameApplyUploadImgReqModel类里,这个类是用于实名申请时图片上传接口的入参实体类,里面包含了图片的base64的string串,占用较大空间。

image

排查mapi底层biz系统,查看EnterRealNameApplyUploadImgReqModel对应的实现类,发现biz中有对图片大小进行限制,最大为2M,但是mapi无限制,怀疑可能为此接口中上传图片过大。

经磊哥点拨,发现sdk中对base串做了加密,并在mapi中做了解密处理,加解密工具为静态(static)工具方法,可能导致内存泄漏。

image

定位到问题后,再使用亮哥推荐的visualVM插件,在本地启了mapi应用,在sdk写了个死循环去调图片上传接口,并故意将照片设置为3M,同时在idea的VM Option中JVM内存调至300M,此时效果如下:

image

可以很清楚的发现,old区增长速度特别快,同时gc次数频繁,并且无法有效的降低old区占用,old区整体呈现递增趋势,很容易发生内存溢出,经过之前的定位流程,猜测为图片本身较大,在亚当区无法容纳该对象时,直接塞到old区,同时加解密方法为静态方法,被持续引用,导致无法进行垃圾回收,导致old区持续递增。

定 案

处理方案:

  • 生产服务器的内存为8G,将堆内存从2G扩到4G

  • 图片上传接口不在走通用加解密流程,在sdk、mapi单独为其封装了一套特殊的加解密流程,base64串不进行加密,直接做拼接处理,其余参数做加解密。处理后效果如下:

image

处理后可以很明显的发现无论是Old Gen区的递增速度还是gc次数相较于之前发生了很大的变化,趋于正常。

案中案-CPU分析

以上过程其实问题已经得到解决,但发现频繁报fullgc的机器,cpu一直占用在10%以上,怀着打破砂锅问到底的态度对cup的问题也进行了下分析:

1、通过top命令查看占用cpu过高的进程

image

可以看到占用cpu的进程PID为7975

2、通过命令查找到占用cpu最高的线程

命令:top -H -p [进程id] top –H –p 7975

image

3、将线程号转化为16进制(jstack线程堆栈中使用的16进制)

printf "%x\n" [线程id]

image

4、 查找线程号对应的线程

执行: jstack [进程id] |grep -A 10 [线程id的16进制]

image

由上图可以看到,一直在占用CPU的线程是CMS垃圾回收线程,由于堆内存占用过高程序又不释放,垃圾回收线程一直在尝试回收内存导致cpu过高。

并案分析-垃圾回收原因

上面再分析触发垃圾回收的时候留了一个小尾巴,为什么老年代和永久代占用不高的时候频繁的发生了full gc呢。由于此应用使用的是jdk1.6,垃圾回收器使用的是CMS,它是基于“标记--清除”算法实现的,特点是在收集结束的时候会有大量的空间碎片产生。空间碎片太多的时候,将会给大对象的分配带来很大的麻烦,往往会出现老年代还有很大的空间剩余,但是无法找到足够大的连续空间来分配当前对象的,只能提前触发 full gc。如果jdk调整为1.7u4及以上即可使用G1垃圾回收算法不会产生大量的空间碎片。

结 案 总 结

JVM问题一般不是很容易遇到,程序有bug或者并发量大的时候均可能导致jvm异常,通过以上问题的分析过程及以往的经验简单总结下排查jvm问题的一般思路:

  • 查看jvm内存和机器CPU情况

  • 内存占用过高,可能是发生内存泄漏,需要导出dump文件借助mat或者是IBM HeapAnalyze来分析内存中哪些对象占比比较高,那些实例较多的对象需要重点分析

  • cpu占用过高时可以通过步骤4的分析定位到具体的线程,程序编码中用到多线程的地方一定要给线程起个有意义的名字不要用默认的名字,这样出问题时方便定位。

上面只是个大概的流程,具体问题还需具体分析,重点还是需要掌握jvm原理并灵活应用

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,816评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,729评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,300评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,780评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,890评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,084评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,151评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,912评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,355评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,666评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,809评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,504评论 4 334
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,150评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,882评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,121评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,628评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,724评论 2 351