干货,一次完整的线上jvm问题排查定位

现象

用户量3千左右,并且业务没有对外开放,业务系统CPU一直居高不下。

问题定位

初步怀疑开发人员逻辑控制不严谨, 导致死循环,因为业务量不大,用户量不大,不可能出现高并发。

执行jps命令找到当前应用pid为8804

jps -l   

执行 top -Hp查找最耗时cpu线程id为9001

 top -Hp 8804

执行printf转换线程id为16进制,得出值为2329

printf "%x
" 9001

执行jstack生成线程快照,查看执行线程为Vm Thread,初步怀疑是频繁的GC导致cpu过高

jstack 8804|grep 2329

执行命令 jmap,查看堆栈信息,看到年老区已使用86% ,如下图:

jmap -heap 8804

执行jstat -gcutil,查看垃圾回收频率,FGC频率非常高,基本确定就是GC回收频繁,导致CPU过高,如下图:

    jstat -gcutil 8804 1000

确认问题代码,执行jmap -dump:format=b,生成堆栈文件,通过MAT进行分析,可以看到JceSecurity这个类就占用大部分内存,如下图:

    jmap -dump:format=b,file=heap.bin 8804

由于IdentityHashMap为static修饰,并且存放过多BouncyCastleProvider这个类,占用了大部分内存,导致full gc频繁回收,查看JceSecurity中的IdentityHashMap,如下图

查找程序中使用BouncyCastleProvider的代码,跟开发人员确认是解密类,分析代码发现每次调用都有可能往静态map中插入新的BouncyCastleProvider对象,如下图:

问题修复

由于前面已经定位到原因是由于每次创建新的对象BouncyCastleProvider导致,因此修改RSAUtil类中BouncyCastleProvider为单例,进行压测观察,如下图:

压测进行2小时,GC回收频率如下图:

内存使用情况:

发表评论
留言与评论(共有 0 条评论) “”
   
验证码:

相关文章

推荐文章