当前位置: 首页 > 科技观察

记一次直播网络内存泄漏排查分析

时间:2023-03-21 16:58:59 科技观察

本文转载自微信公众号《会笑的建筑师》,作者雷小帅。转载本文,请联系LoveSmile的架构师公众号。大家好,我是雷小??帅!大家的春节过得怎么样,反正我挺丧的。本来给自己定了很多计划,但最后的执行效果是这样的:写几篇技术文章,看几本技术书,玩几天,走亲戚,看电影。向上。今天的文章就带大家分析一个内存异常的问题。也是新年第一篇技术文章。Goodluck~~~我们有一个新服务运行了一段时间,但是总是堆内存不足,大量FullGC,有些实例甚至出现内存溢出错误:java.lang.OutOfMemoryError:Java堆空间但是为什么会内存溢出呢?据说访问量不是很高,所以进行了如下调查分析。1.怀疑内存泄漏。进入APM监控系统查看实例内存状态。将时间线延长到一天,可以看到内存有缓慢上升的趋势。初步怀疑是内存泄漏。2、HeapDump获取机器ip,联系运维人员dump机器上的heap,dump命令:/xxx/jdk1.8.0_212/bin/jmap-dump:live,format=b,file=/xxx/xxx.hprofprocessID下载heapdump文件Xxx.hprof到本地。3、下载HeapDump分析工具常用的分析工具有MAT和JProfile。本文以MAT工具为例进行分析。工具下载链接如下:https://www.eclipse.org/mat/downloads.php注意:如果你本地已经安装了JDK11+,直接下载最新的即可;如果你本地安装了JDK8,建议下载1.9.2版本。4.将Dump文件导入MAT工具MAT是eclipse的插件,免安装,双击打开即可使用。打开下载的dump文件5.分析dump文件打开内存泄漏分析报告,可以看到SessionFactoryImpl对象使用了149M内存,占总内存的25%,这肯定是不正常的。SessionFactoryImpl类与数据库有关。服务代码使用JPA作为持久层框架。它应该与JPA有关。继续分析吧。我们打开内存树往下挖,可以看到对象QueryPlanCache占用了很多内存。QueryPlanCache表面上的意思是:查询计划缓存。具体意思用google查一下。简单来说,Hibernate会缓存sql语句,减少重复编译,方便直接命中,提高效率。在使用sqlin的时候,如果in后面的参数不同,hibernate会把它缓存为不同的sql,从而缓存大量的sql。缓存的大小是多少?查看官方文档,如果没有配置,这个缓存的默认最大值是2048。StackOverflow上也有用户反馈这个问题:https://stackoverflow.com/questions/31557076/spring-hibernate-query-plan-cache-memory-usage7.分析结论drawio服务中存在大量sqlin语句,后面的in参数不同导致Hibernate缓存了大量的sql语句,占用大量堆内存。8、解决方案(1)添加配置参数限制缓存大小参数解释:https://docs.jboss.org/hibernate/orm/5.4/userguide/html_single/Hibernate_User_Guide.html#configurations-query(2)Explanation中改进sql缓存效率参数:https://docs.jboss.org/hibernate/orm/5.4/userguide/html_single/Hibernate_User_Guide.html#configurations-query