使用Eclipse Memory Analysis分析线上OOM内存泄漏的重要工具之一
当主机访问探测服务地址时访问失败,会以告警的方式发送邮件到系统负责人。一但接到这样的邮件就是大事故。
经与主机负责人沟通后会提供一个类似于java_pid19098.hprof.gz 文件,解压后文件java_pid19098.hprof 大约两个G左右,这玩意用啥打开啊。
一开始接到这玩意有点蒙,问主机负责人,这东西咋看。人家会很客气的告诉你,不知道。
当自己束手无策时,领导电话过来了,问这是啥情况。你只能回答,正在分析。。。。。
还好提供Eclipse Memory Analysis工具可以打开此文件,对此文件进行分析
1.使用Eclipse Memory Analysis工具需要占用很大内存, 建议关掉你所有应用程序,因为这个工具会让你机器卡死,影响你分析问题的速度。 一开始我就卡死一次~~~
当一开始使用此工具时,没有MemoryAnalyzer.ini 文件,只有运行一次会生成这个文件。
修改此文件,使用文本文件工具打开,在最后添加 -Xmx4G ,
-Xmx4G表示 设置JVM最大可用内存 4G
2. 使用此工具打开此文件(File->Open file ),MAT解析完成后会出现如下图提示
查看内存泄漏分析报表
只是为了查看内存泄漏问题,我使用默认选项目直接 完成。
上图有个Leak Suspects 报表,我的目标很明确,直奔主题,会打下以下内容
Leak Suspects
发现有三处造成内存泄漏问题
1.第一个问题
上图发现 The thread java.lang.Thread @ 0x777965dd8 default task-20 keeps local variables with total size 345,177,112 (21.49%) bytes ,线程存储本地变量345,177,112 (21.49%) bytes, 天来,这就是造成OOM的原因之一
图上还有两个连接,可以查看详情内容,
通过查看内容发现自己很熟的内容了。DataQueryController.java:54 看出这个文件中第54行造成的根本原因了。
2.第二个问题 , 第三个问题,使用同样的方法可以看出,是一个地方造成。引发三个地方内存泄漏。
在上图中分析 java_pid19098.hprof 时 Dominator Tree进去,可以列出哪个线程,以及线程下面的哪些对象 占用空间,根据占用空间大小排序。
打开第一个又看出我们熟悉的内容
可以得到内容
select t1.* from app_retail_cloud_records t1 left join (select distinct day_id,oms_order_no from dpms_b2b_dpa_cmmdty_sale_detail_d where day_id in ('20190107','20190108','20190109','20190111','20190114')) t2 on t1.oms_order_id = t2.oms_order_no and t1.stat_date = t2.day_id where t2.oms_order_no is null
这是因为SQL引发内存泄漏的原因,剩下的就是我们通过什么办法解决这个问题。 得到解决方案后,可以编写事故原因汇报领导了!!
-----
欢迎关注微信公众号“零售云技术”,后续文章持续更新