java 调用dll内存泄露_【JAVA】记一次典型jvm内存泄漏

在一次持续十分钟的压力测试中,发现Java应用存在内存泄漏问题,QPS从8000逐渐降至3000。通过JVM监控工具观察到GC时间异常,尤其是老年代GC时间过长,表明存在内存无法回收的情况。问题根源在于一个未加锁的线程不安全LinkHashMap,导致内存不断膨胀。修复代码,增加同步控制后,长时间压测显示内存正常回收,QPS恢复到8000,且两天内保持稳定。
摘要由CSDN通过智能技术生成

目录

一、问题概述

在持续十分钟的压力测试中,单机QPS从8000陆续降低至3000的过程中发现的内存泄漏。

首先看一下压测计算的数据:

被压测的机器:

机器配置:4核8G

单机预计QPS:8000左右,不超过9000

平均响应时间:12~13ms

发起压测的执行机:

设置单机并发数:60

执行机数量:2台

由此可以计算出进行压测的QPS数据:

平均响应时间为12ms,单机60的并发数,则单机的最高QPS为 60/0.013 = 4600 左右

设置持续上涨4分钟,达到峰值,则可得出:

刚开始时并发量为:60 / 4  *2 = 30 的并发量,QPS = 30/0.013 = 2300

持续4min后:慢慢上涨到60*2的并发量,峰值 QPS = 120 / 0,013 = 9230

压力合理,可以缓慢达到压力的峰值并维持压力。

二、发现问题

整个压测过程分为2步,每步压测5分钟。压测完成后,查看压测报告:

首先是jmeter产出的报告:

8defafcdd5e443180881e3ebb21594ee.png

看上去没有问题,达到了预期的效果,但是当对该机器进行第二次压测的时候,发现它的QPS已经下降了30%

第二次压测产出的报告:

1f10e222594b6137aaa8c53493996da3.png

这一次就有些困惑了,讲道理两次相同条件的压测结果差距不应该这么大,绝对是哪个地方有问题,导致qps上不去,像这种情况,多半是JVM的问题。

于是使用jdk自带的jvm监控工具对压测过程进行了监控。

将服务器重启一次,继续进行两步压测,这次从监控中直接看到了问题:

第一次报告:

dc74f791f509946a24b04512e52c3140.png

GC时间报告:

261881457c2f122c8e4b23baca433f08.png

很明显,jvm的状态是有问题的:

第一张图中的堆内存使用量居然下不来,说明了内存无法被回收,说明了存在内存泄漏的问题。

第二张图中显示老年代做GC的时间并不长,这应该是应该有的现象,这也是为什么本次压测QPS能到预期值

第二次报告:

00e3cc4ae0f9f877c314fee11e07d2aa.png

GC时间报告:

3790ce0559dd22c5470e5cc7f0ce350e.png

看似JVM已经完成了GC,但是仔细看它的GC时间,老年代的GC整整持续了2分钟,这其实是不正常的。

这个时候打开JVM的内存选项,查看了老年代的jvm情况,发现它有整整2个G的内存无法被回收,而我这台机器总共才8个G。

(虽然jvm的老年代图弄丢了,但是从上面的图可以也可以看出来,它是有几个G的内存没有被回收的)

后面当我再对其进行压力测试,它的QPS直接降到了3000左右。而它的老年代GC时间一直在变长。

三、解决问题

上面已经找到了问题的原因,后面发现代码问题就很简单的

本项目是一个网关项目,内部有个linkHashMap需要存放某些数据,而该map内部做了舱壁限制了总map的size。但是linkHashMap是线程不安全的,代码中并没有对它的put操作进行加锁处理,导致它的内存不断膨胀,存放的数据不断的放入老年代,最后无法被老年代回收。

代码优化完成后,对它进行长时间的压测,查看它产出的报告:

02311da7e87f3ebae8d09a8d7c3032e1.png

这就很合理了,FullGC之后内存就降下来了,QPS又回到了8000。

为了测试它的稳定性,后续对它进行了持续两天的压力测试,没有出现性能问题。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值