最近碰到的一次内存溢出问题,记录一下(只记录正确找出问题的方法,其它的各种不提),也以此来重新开始自己的博客园之旅。
Tomcat打包发布后,一切OK,回归测试也没问题。但是运行一段时间后却报内存溢出,服务器shutdown,重起数次失败后直接停掉。
运维人员不在,拿不到堆栈日志,先对那段时间的人员操作日志结合catalina日志进行分析。发现开始出问题的时间,开始出现某一个页面的操作,初步怀疑是这个页面相关的代码引起的;接着就看相关代码提交日志,居然没看出问题。后来找运维要到堆栈日志,问题还是定位到这里,在经验更丰富的同事的帮助下,定位到以下代码:
select id, other_id from tbl where 1=1
<if test="ids != null ">
and other_id in
<foreach item="item" index="index" collection="ids" open="(" separator="," close=")">
#{item}
</foreach>
</if>
如果ids==null,就会把整个表里的数据扫出来,而tbl表中的数据有1千多万,直接把内存撑爆了。而最终的原因就是在调用方法前没有对ids的list进行非空判断。
总结:对于java的集合,使用之前尽量进行非空判断,可以用CollectionUtils.isEmpty()方法;对于大表的sql语句,一定要检验所有if判断条件都不成立时的查询结果。
新闻热点
疑难解答