天天看点

工作中一次内存溢出,查到到解决问题记载

由于公司信息安全问题,一些文件、照片无法取出,只能口述一下

介绍一下问题背景:这是一个老项目,和信用卡相关的系统,每天凌晨会有多个定时任务启动,把文件里的数据读取出来,生成待办任务,或者查询数据库相应的数据生成相应的代办任务,等类似的任务推送给卡商(信用卡处理中心),每天的数据量大概几万,如果前几天数据有挤压,等服务通了以后就会有几十万或者更多的数据产生等待处理;

事发时间:国庆假期;

异常:内存溢出;

处理方式:重启服务器后,服务正常使用;

后续跟进:一开始没有宕机文件走了很多弯路走了很多弯路,没有找到根本原因;只知道某一行代码那报错导致的内存溢出,但是那行代码只是查询数据库得到一个list,然后for循环list;数据量并不是很大,创建的对象并没有被持续持有,不至于导致内存溢出;

最初的解决办法是一个不是办法的办法,去监听服务如果服务挂了,或者没有正确的往数据库指定的某张表写入数据,则停止服务,再拉起来;但是这个方法治标不治本;

后来拿到dump文件,用IBM HEAPANALYZER 打开发现百分之99的内存都被用来存在MQreceiver对象,通过IBM HEAPANALYZER一层层查看最后发现是XML中配置的transport类中(用来调用SOA上发布的服务)创建的MQreceiver对象,我们通过debug断点把整个调用流程走了一遍,并没有发现什么异常,后来在另一个项目中(同样也用到SOA上的服务)也通过debug断点把流程走了一遍,发现每次soa调用完成时,会调用MQreceiver类里的close()方法,close方法中就会销毁MQreceiver对象引用,等垃圾回收的时候就会把MQreceiver对象给回收掉,最终比对了一下MQreceiver对象那个jar包发现老项目中用到jar包版本是1.0版本,新项目用到的jar包是7.0以后的版本,由于1.0版本里并没有对MQreceiver对象的引用及时的销毁,导致如果过多的调用SOA服务时就会创建很多个MQreceiver对象,长时间的累积就是OutOfMemory,最后把低版本的和MQ相关的jar包全部换成高版本的MQ jar包问题得到了解决。

问题说的可能比较简单但是实际上走了很多弯路没有叙述,本文只是记录一下这一次遇到的bug,希望对以后有帮助,也希望对各位看官有所帮助,不喜勿喷,多多包涵

继续阅读