php守护进程内存溢出,记一次通过Memory Analyzer分析内存泄漏的解决过程

443149798b959e7912c0265d0e1a23d1.png

一、状况描述和分析

遇到的问题:项目新打的版本,过不了多长时间,项目就会挂掉。

状况就是处于一种假死的状态。索引查询都很慢,几乎进行不了任何操作,慢慢卡死。

然后我们再发版时,只能基于之前打好的war包,替换或者增加class文件。

情况对比及分析:

由于之前代码做过一次大整顿,提交的代码比较多,所以通过回滚版本的方式解决,比较困难。

一是因为整顿的成果不能白白抹杀;二是那么多文件,靠人工挨个对比查找,比较困难。

二、解决方案一

之前, 一直对目前项目的打包方式心存质疑,所以这次发生问题时,我

首先怀疑的对象是Jenkins和生产的Tomcat服务器

。我通

过堡垒机连接到生产时,发现通过Jenkins启动应用程序,会启动两个两个tomcat进程

c161e0f1139654c1299b99e878329e7f.png

然后,这似乎更加坚定了我的看法,马上就找到了运维,但是经确认后,是没有问题的。

一个是用root用户启动的,一个是用tomcat用户启动的。

一个守护进程,一个应用进程。

三、解决方案二

排除了服务器的问题,开始正面考虑程序的问题。

重新发项目有问题的版本,Dump下来的日志,然后迅速回滚观察。单台机器的dump日志有5个G:

通过Memory Analyzer分析,在Leak Supects Report 视图中,有如下分析结果:

e9e5771ac24430b9e2026f87cab398a4.png

上图所示,共有三类问题a、b、c;

还有一些其他的,类型为d。

先来看第一个问题(后来发现,前几个问题都是同一个问题)

0831a9a3aa9cab47ef81dd52b538d932.png

先点开Details看一下:

e1fa0180eeda574f9e382703255feaff.png

上图显示了一个很明显的有问题的线程:

地址是0x7c8ff3df0 ,名称为pool-16-thread-1。

通过《Accumulated Objects in Dominator Tree》视图可以看出,在该线程中,存在一个大的List对象,List对象内存放了大量的mysql的jdbc对象。

我们想看看JDBC对象里面堆放了哪些数据

。接下来我们打开《open dominator tree for entire heap》这个视图:

f643c57a9d45ea45e48ec7f1de817089.png

找到名为0x7c8ff3df0 pool-16-thread-1的线程。

如图也能发现,

这个线程占用了大量的空间未释放

。一层层打开里面的存放的对象:

b4c6156626d8c3a0a632689036a6d3d7.png

这里的数据,是我们的一张用户表的数据。所以这就可以得出结论:

一个线程内,一个list内存放了大量从数据库中获取的用户对象!

想到这里,

我们又去看了b、c的问题描述,也是同样的问题

。估计是在不同时间点,通过gc已经回收了部分。

然后,我刚才看了a问题的details信息,接下来我们看下a的stacktrace 堆栈信息。

3a894edca3d7da34a0c88b91d5c1fe19.png

如上图,

问题就很明显了,在Service的112行中,调用的findByCustomerID方法中,有扫描全表的操作

。经过分析,找到对应的位置,对应的代码为:

customerID = StringUtils.isNotBlank(customerID)?customer.getCustomer().getCustomerID():null;

Customer oldCutsomer = customerService.findByCustomerID(customerID);

显而易见,

流程走到这里时,customerID永远为空,那么customerService.findByCustomerID(customerID)方法,会执行扫描全表操作

由于该表数据量巨大,开发所认为的用户每次执行的索引查询,实际上都成了慢查询,而且需要返回全表数据。大量线程过来,占用大量数据库连接,导致数据库连接数不够;而每个线程处理时,需要大量时间,导致项目处于一种假死的状态。

四、总结分析

1、在工作中一定要规范代码管理,才能提升开发效率,降低企业遭受损失的风险;

2、通过这次实践发现,目前开发权限小,导致跨部门协同效率不是很高,接下来的开发中,立项之初就建立项目开发流程,从而提升开发效率;

3、解决问题的方法遇到瓶颈,尝试第二种方法,多角度多层次对问题进行突破。

⭐️⭐️⭐️欢迎加入“宜信技术交流群”。进群方式:请加小助手微信(微信号:creditease_tech)。

◆◆◆ ◆◆

如需转载请与小助手(微信号:creditease_tech)联系。发现文章有错误、对内容有疑问,都可以通过关注宜信技术学院微信公众号(CE_TECH),在后台留言给我们。我们每周会挑选出一位热心小伙伴,送上一份精美的小礼品。快来扫码关注我们吧!

⏬点击“阅读原文”查看更多技术干货

74341aa541b0774d8f7cbd1c7016e8c6.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值