前几天,测试环境服务器突然宕机了,登录到服务器上,定位具体问题。
1.查看Java进程
ps -ef | grep java
2.查看JVM状况,发现老年代已经被占满了,肯定有问题
jstat -gc <pid> 2000 10

3.在服务器上初步查看JVM情况,发现占用内存最多的居然是个LinkedHashMap
jmap -histo:live <pid> | head -30

5.导出dump文件,进一步分析
jmap -dump:live,format=b,file=heapdump.hprof <pid>
6.我们使用MemoryAnalyzer来进行分析,网上很多下载地址都是假的,直接到eclipse官网上下载。
https://eclipse.dev/mat/download/previous/
7.导出文件后,发现文件非常大,8.5个G,给分析带来了很大困难,用MAT来分析,MAT直接报内存溢出。报java heap space。
8.调整MAT配置,继续分析

9.经过漫长的等待,终于打开了这个hprof文件,MAT的分析很智能,可以看到具体是哪个对象占了这么多的内存

10.再经过代码定位,定位到了原因,是个加解密方法,每次都新建一个对象。
有一个定时任务会去请另一个系统;而测试环境这个系统挂掉了,所以导致不停地去请求这个系统,并且触发加密逻辑,不断地新建BouncyCastleProvider对象,导致把内存撑爆了。

11.问题解决
把BouncyCastleProvider改成单例的,就不会每次都新建了。
final static BouncyCastleProvider BOUNCY_CASTLE_PROVIDER = new BouncyCastleProvider();
private static Cipher generateCBCCipher(String algorithmName, int mode, byte[] key, byte[] iv)
throws Exception {
Cipher cipher = Cipher.getInstance(algorithmName, BOUNCY_CASTLE_PROVIDER);
Key sm4Key = new SecretKeySpec(key, ALGORITHM_NAME);
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
cipher.init(mode, sm4Key, ivParameterSpec);
return cipher;
}


844

被折叠的 条评论
为什么被折叠?



