获取到dump文件,大概四个G左右,使用JDK自带的jvisualvm工具分析(可以跳过jvisualvm直接使用MemoryAnalyzer进行分析)。
运行jvisualvm,选择【文件】-->【装入】
找到对应的dump文件
装入好后查看到实例数最多的几个类,如下图所示。
前面三个类是常用的工具类,很多地方都有使用,如果从这里入手排查,难度会非常大。
第四第五的可以定位到类java.security.Provider
查到类java.security.Provider的子类有十几个,一个个去查询工作量也非常大
接下来使用MemoryAnalyzer分析一下该dump文件,因为该dump文件比较大,需要修改MemoryAnalyzer.ini文件的最大堆内存配置
打开MemoryAnalyzer,选择【File】-->【Open Heap Dump…】
找到dump文件,选择打开
使用Leak Suspects Report进行分析,报告将显示系统可能存在的内存泄露情况
Leak Suspects Report定位到类javax.crypto.JceSecurity,点击下方的Details
进一步定位到类org.bouncycastle.jce.provider.BouncyCastleProvider
根据类org.bouncycastle.jce.provider.BouncyCastleProvider定位到问题代码
Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5PADDING", new BouncyCastleProvider());
优化后代码如下
private static BouncyCastleProvider decryptBouncyCastleProvider = null;
private static BouncyCastleProvider getDecryptProviderInstance() {
if (decryptBouncyCastleProvider == null) {
synchronized (DesUtils.class) {
if (decryptBouncyCastleProvider == null) {
decryptBouncyCastleProvider = new BouncyCastleProvider();
}
}
}
return decryptBouncyCastleProvider;
}
Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5PADDING", getDecryptProviderInstance());