使用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解析完成后会出现如下图提示

使用Eclipse Memory Analysis分析线上OOM内存泄漏的重要工具之一

查看内存泄漏分析报表

只是为了查看内存泄漏问题,我使用默认选项目直接 完成。

使用Eclipse Memory Analysis分析线上OOM内存泄漏的重要工具之一

内存泄漏分析首页

上图可以看到它的大部分功能

1.Histogram 列出内存中的对象,对象的个数以及大小

2.Dominator Tree 列出哪个线程,及线程下的对象占用空间

3.Leak Suspects 通过MA自动分析泄漏的原因

上图有个Leak Suspects 报表,我的目标很明确,直奔主题,会打下以下内容

使用Eclipse Memory Analysis分析线上OOM内存泄漏的重要工具之一

Leak Suspects

发现有三处造成内存泄漏问题

1.第一个问题

使用Eclipse Memory Analysis分析线上OOM内存泄漏的重要工具之一

上图发现 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的原因之一

图上还有两个连接,可以查看详情内容,

使用Eclipse Memory Analysis分析线上OOM内存泄漏的重要工具之一

通过查看内容发现自己很熟的内容了。DataQueryController.java:54 看出这个文件中第54行造成的根本原因了。

回到首页,Histogram 视图 ,列出内存中的对象,对象的个数以及大小

使用Eclipse Memory Analysis分析线上OOM内存泄漏的重要工具之一

Histogram 视图

可以通过下图查看占用345,177,112 (21.49%) bytes 是哪个对象 占据首位

使用Eclipse Memory Analysis分析线上OOM内存泄漏的重要工具之一

Open In Dominator Tree

输入java.util.LinkedHashMap$Entry, 如下图

使用Eclipse Memory Analysis分析线上OOM内存泄漏的重要工具之一

查看某个对象占用内存空间

完成后,分析出java.util.LinkedHashMap$Entry对象中占用内存空间大小,查看下图可怕的对象

使用Eclipse Memory Analysis分析线上OOM内存泄漏的重要工具之一

2.第二个问题 , 第三个问题,使用同样的方法可以看出,是一个地方造成。引发三个地方内存泄漏。

在上图中分析 java_pid19098.hprof 时 Dominator Tree进去,可以列出哪个线程,以及线程下面的哪些对象 占用空间,根据占用空间大小排序。

打开第一个又看出我们熟悉的内容

使用Eclipse Memory Analysis分析线上OOM内存泄漏的重要工具之一

可以得到内容

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引发内存泄漏的原因,剩下的就是我们通过什么办法解决这个问题。 得到解决方案后,可以编写事故原因汇报领导了!!

-----


分享到:


相關文章: