JVM内存溢出导致的CPU过高问题排查案例

问题背景:

近期针对某接口做压力测试的过程中发现,某接口在用户量3千左右,并且业务没有对外开放,CPU一直居高不下。

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

 1.通过jstack查找出对应执行线程是Vm Thread 线程,初步怀疑是频繁的GC导致cpu过高。

 2.查看堆栈信息 jmap -heap 16190,如下图:

JVM内存溢出导致的CPU过高问题排查案例

看到年老区已使用86%

3.查看垃圾回收频率,再次确认:jstat -gcutil 16190 1000

JVM内存溢出导致的CPU过高问题排查案例

FGC频率非常高,基本确定就是GC回收频繁,导致CPU过高。

4.确认问题代码,执行jmap -dump:format=b,file=heap.bin 16190,生成堆栈文件,通过MAT进行分析,如下图:

JVM内存溢出导致的CPU过高问题排查案例JVM内存溢出导致的CPU过高问题排查案例

通过层层定位和分析,得出JceSecurity这个类就占用大部分内存,点击Dominator Tree进行分析,如下图:

JVM内存溢出导致的CPU过高问题排查案例

 

由于IdentityHashMap存放过多BouncyCastleProvider这个类,占用了大部分内存,查看JceSecurity中的IdentityHashMap,如下图:

JVM内存溢出导致的CPU过高问题排查案例

现在已经确定是由于map是static修饰导致,导致存放的类不能被jvm回收导致

5、查找程序中使用BouncyCastleProvider的代码,跟开发人员确认是解密类,如下图:

JVM内存溢出导致的CPU过高问题排查案例JVM内存溢出导致的CPU过高问题排查案例

JVM内存溢出导致的CPU过高问题排查案例

JVM内存溢出导致的CPU过高问题排查案例

6、修改RSAUtil类中BouncyCastleProvider为单例,在此进行压测观察,如下图:

JVM内存溢出导致的CPU过高问题排查案例

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

JVM内存溢出导致的CPU过高问题排查案例

内存使用情况:

JVM内存溢出导致的CPU过高问题排查案例

 

 

 JVM内存溢出导致的CPU过高问题排查案例

 至此,问题已经解决