案例背景

环境:Linux + WAS + DB2 压测工具:Loadrunner 问题描述:性能压测过程中出现内存溢出。

分析过程

查看JVM曲线,发现used heapsize呈上升趋势不断增大,直至内存溢出。

由于是长时间压测后累积产生的内存溢出,这类内存溢出在javacore里面往往找不到相关线索。

接着,分析heapdump文件,从溢出文件来看,溢出对象为HashMap,达到5.4万个左右。

往上追溯,发现该HashMap跟一个名为NameParameterStatement的jdbc查询结果集有关。

咨询开发负责人得知,NameParameterStatement是框架里面的一个缓存对象,用于存储解析过的SQL。而业务系统开发人员未采用预编译的方式编写代码,因此每次发起的SQL都是不一样的都需要缓存,也就导致NameParameterStatement对象越来越大直到内存溢出。

问题解决

开发人员给出解决方案,将NameParameterStatement缓存的SQL限制在1万条以内,采用LRU方式进行清理。

案例小结

1.对于长时间累积缓慢造成的内存溢出,往往只能通过heapdump文件来找出泄露的对象; 2.在使用缓存时,一定要谨慎留意该缓存是否会无限增大,此案例的问题在于框架在缓存数据时,未考虑到当调用方未采用预编译方式进行编码的情况下,缓存会无限增大而导致内存溢出;

本案例相关的一些素材资料,可从下面网盘获取。 链接:https://pan.baidu.com/s/1Xi42L1ZZSCHrQJj3A1migg 提取码:4ddp