定位JVM内存泄漏

前几天,测试环境服务器突然宕机了,登录到服务器上,定位具体问题。

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;
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值