分析JVM出现的内存持续增加的性能故障手册
前言
本文通过常见的性能文件为例,提供简单清晰的思路去快速定位问题根源,从而可以快速解决性能故障。
性能问题介绍
在性能测试工作中针对Java程序最重要的是要关注JVM的内存消耗情况,JVM的内存消耗情况源于gc情况。YGC的不稳定以及YGC的太频繁都会增加CPU等资源的使用。以典型的订购业务的性能问题为例介绍如何分析这类问题:
订购业务在大多数现场性能测试阶段都会发现性能问题,目前V81版本在基于去掉流程实例后,在进行长时间的稳定性测试发现随着稳定的压力,业务响应时间是越来越长。
性能问题分析
上面的问题是一种常见的性能问题,导致JVM内存增加的根本原因就是由于某个大的对象存活时间比较长,占用Yang区和Old区空间比较大,从而引发YGC很频繁同时也伴随着FGC。
分析问题步骤:
- 监控JVM的内存消耗
很明显JVM消耗会超过3g这个是不正常的
- 分析gc情况
使用jstat指令:jstat -gcutil pid
可以发现YGC是不断增加
详细分析YGC的情况将打印的gc.log使用GCViewer分析工具分析:YGC太频繁
- 分析具体哪些对象导致
定位JVM的gc回收不正常后,需要进一步分析是哪些对象占用比较大。此时会有很多方式,但是强烈不建议你抓dump(如果是现网需要禁止抓dump会造成业务长时间的中断),建议使用:jmap – histo pid
从上图可以发现:
com.ztesoft.zsmart.bss.cc.abe.profile.SubsUppInst 这个对象实例大概占了0.5g。
然后进一步定位:jmap -histo:live pid
所以问题基本定位:
业务侧先分析下为什么很低的TPS会有这么多的SubsUppInst 对象。 主要是这个引起的GC波动,问题其实已经明确了。
- 性能问题分析
目前V81版本在基于去掉流程实例后,在进行长时间的稳定性测试发现随着subs_upp_inst个性化实例表单个subs_id对应的记录不断增加后,程序对于JVM内存的消耗是越来越多,会引起YGC次数是越来越频繁,同时也会出现FGC。为了保证系统长时间的稳定运行是一定要避免FGC,同时YGC的回收要趋于稳定。因为YGC的越频繁,也就会对于CPU消耗会明显增加,同时影响业务响应时间。
- 性能问题优化点
性能问题分析如下:
A. 如果不会有同订户下,订购几百次的场景,那么这个性能问题就不会出现
B. WsModUserIPP接口,如果wom需求没有针对IPP进行修改,删除操作,这个性能也不会出现 (需要简单优化下代码)
C. 不使用公共提供的subs_upp_inst捞取逻辑,原有的逻辑是将subs_id下所有生效的ipp都会捞出来给定制,然后定制开发考虑是否需要过滤。修改需要新开发接口在捞取的时候就过滤掉捞取的数据量(取第一条匹配subsId,offerId和state的记录)。除此之外在下订单和订购完成后多出代码都是全捞的记录,所以全量走查后全部改掉。
问题总结:
- 需要你对JVM有一定的了解,需要知道引起YGC和FGC的原理
- 需要掌握常规的gc日志抓取手段
- 需要掌握分析gc.log的分析工具GCViewer
- 需要掌握jstat和jmap的常规命令,需要知道指令对业务性能影响程度
- 需要掌握订购业务逻辑
以上以案例介绍针对这类问题如何去分析。