背景
渠道系统上线新资方,开始放量后一段时间出现系统响应时间较长,CPU负载及堆内存缓慢升高,最终导致内存溢出,系统崩溃。
业务上导致还款分账跨天,用户逾期。
排查
项目启动参数配置
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/Users/apple/Desktop/heap
利用JVISUALVM分析DUMP文件
查找堆中占用内存最大的前几个对象
image.png
查看第二个MAP对象
image.png
对比JceSecurity源码
image.png
继续查看TABLE里的对象
image.png
发现都是BouncyCastleProvider的对象
排查最近上线的资方代码,发现是一个加解密工具类中使用了new BouncyCastleProvider()
资方提供加解密工具类RSAUtils存在BUG
发现类中很多方法存在如下代码
原代码
public static final String KEY_ALGORITHM = "RSA";
Cipher cipher = Cipher.getInstance(KEY_ALGORITHM,new BouncyCastleProvider());
从Cipher.getInstance往上追踪,发现new BouncyCastleProvider()最终都会都放到verificationResults中,而这个verificationResults是一个静态对象,无法被JVM回收,资方接口调用量高的话最终都会导致内存溢出
image.png
更改后代码
private static final Provider DEFAULT_PROVIDER = new BouncyCastleProvider();
public static final String KEY_ALGORITHM = "RSA";
Cipher cipher = Cipher.getInstance(KEY_ALGORITHM,DEFAULT_PROVIDER);
网友评论