Java内存泄漏问题分析

内存泄漏也是一个老八股文了,下面来看看实际项目中内存泄漏的场景分析

时间回到9月某一天


分析阶段一

现象:在当时各种请求在那段时间响应很慢,特别是 kafka异步消费线程

不足点:当时主业务基本不可用,有点急,未及时dump(当时大家没往GC那方面想,单纯以为流量大消费不过来)

第二天系统拉了日志也还未分析出来,只是临时增加了kafka消费线程的数量,单机从2扩到10,两台机器共计20消费线程,服务都重启了一遍

又过去了几天,来到了节假日流量高峰期


分析阶段二

leader在群里发了几个阿里云告警信息,内存告警(这个时候已经距离上次程序重启好几天了)

dba也在群里发了异常信息,有发截图(截图中大量连接状态为 CLOSE_WAIT 以及 重复ip:121.51.50.140和121.51.58.151):句柄数一直在涨

        注:当时我回复dba的话:句柄增加,在我印象里,业务代码里应该没什么本地IO操作,网络IO的话主要是我们服务之间会频繁的进行远程调用(-_-害 把订单模块给漏了,这里会去调阿里/腾讯进行支付)
            当时在群里询问小伙伴有没有可以 根据句柄反推请求的方法,却把截图中的两个关键信息给漏了,还是经验不足 -_-


 负责订单的同事上线了,发现两个突破点:
            1、大量的连接状态是 CLOSE_WAIT
                如果一直保持在CLOSE_WAIT状态,那么只有一种情况,就是在对方关闭连接之后服务器程 序自己没有进一步发出ack信号。换句话说,就是在对方连接关闭之后,程序里没有检测到,或者程序压根就忘记了这个时候需要关闭连接,于是这个资源就一直 被程序占着。个人觉得这种情况,通过服务器内核参数也没办法解决,服务器对于程序抢占的资源没有主动回收的权利,除非终止程序运行。
                所以如果将大量CLOSE_WAIT的解决办法总结为一句话那就是:查代码,因为问题出在服务器程序里头啊

              2、重复ip:121.51.50.140和121.51.58.151  (此为腾讯云服务器)

121.51.58.151:https (CLOSE_WAIT)
121.51.58.151:https (CLOSE_WAIT)
121.51.50.140:https (CLOSE_WAIT)

为什么有大量的连接处在CLOSE_WAIT状态? (qq.com)

TCP通信过程中time_wait和close_wait产生过多的原因和解决方法_time_wait连接过多的原因-CSDN博客

同时根据这两点定位到代码:
            1、获取支付渠道配置(微信支付 微信支付分....)
            2、根据获取到的配置判断httpClientMap中是否存在(会对比版本号),不存在则创建一个WechatPayHttpClient(或支付宝 或其他渠道)然后写入httpClientMap
            
            乍一眼看流程没啥问题,其实在第一步每次都会获取一个“新”的渠道配置(版本号不一致),因渠道配置缓存的set get使用的key不同,等同于没缓存(这个缓存为本地hashmap,value为连接对象)

             没缓存所导致的问题就是 每次支付都会重新build一个新的连接去调用支付渠道进行支付,然后每次都会将这个连接放入map中,此时内存就会随着支付的请求数量而持续增高,并且连接对象也不会被释放掉。在修复之前也通过dump文件看到最大的对象即是这个存储连接对象的map,最终展现的情况就是一直Full GC,所有业务请求在那段时间响应非常慢,连一个最基本的主键查询都很慢-_-


写到最后:此文是一位优秀且帅气的同事所排查分析,作为小菜鸡的我只能在此案例中默默学习学习๐·°(৹˃̵﹏˂̵৹)°·๐

  • 87
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值