背景:
此系统功能上大抵分为两部分,一个是Web的管理平台,其二是定时检测、路由、转换发送报文的后端功能。系统主要计算在后端功能。管理平台的使用量很小,基本是配置及状态查看。
现象:
在测试数据中,处理5万单的文件。据相关开发人员描述,系统内存泄漏,系统运行越来越慢。
查看:
由开发人员提供的函数执行时间统计表来看,函数的平均执行时间并没有明显的降低。(此处开发人员将关注点放在了总时间)
经过使用工具查看,系统的内存使用持续增加,一直没有回落,两个小时内一直稳定在2G左右。
思路:
1、内存稳定2G不再增长,有可能是测试数据量的问题,也可能是内存使用基准就是2G,后续基本不再增长。
所以,最好再增长数据量做一次测试,以进一步确认。
2、假设内存泄漏,那么通过查看堆栈信息。由jvisualvm.exe查看实例数量统计,发现除了integer,char[]等基础类型数量非常大。而与系统有关的类的实例很少,或者处在循环中,有稳定的波动。
联想到可能有程序员定义全局的字段,导致一直累加增长。
通过关键字查找,未发现有此类现象。
再查看列表,除了基础数据类型多之外,HashMap及HashMap$Entry的实例也很多,达到百万个实例。通过查看工程代码,使用到Map的地方一般都在函数内的局部变量,不可能造成这么多的实例。
最后采用随机的方式,查看Map所关联的实例,发现都与HQLParser有对象相关。
由此联想到,可能是开发时,一些SQL或者HQL采用拼字符串的方式,且没有使用占位符。猜想Hibernate内部可能对这些SQL/HQL的语句进行一些缓存。导致HashMap的实例量剧增。
(最后通过测试,证实确实是此问题。错误的开发习惯导致的性能问题不是重点,重点是记录一些查找问题的过程与思路)
本文探讨了一款系统在处理大量数据时出现内存泄漏和运行速度减缓的问题。通过分析开发人员提供的函数执行时间统计和内存使用情况,发现内存使用稳定在较高水平,疑似存在内存泄漏。进一步排查后,发现可能是由于错误的SQL或HQL拼接方式导致的HashMap实例数剧增,从而引发内存泄漏。最终,通过验证证实了这一问题,并强调了记录问题解决过程的重要性。
8848

被折叠的 条评论
为什么被折叠?



