Java内存泄漏问题分析

2024-01-09 09:21:36

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

时间回到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,所有业务请求在那段时间响应非常慢,连一个最基本的主键查询都很慢-_-


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

文章来源:https://blog.csdn.net/weixin_44700876/article/details/135332592
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。