你的位置:首页 > 信息动态 > 新闻中心
信息动态
联系我们

MEM分析系列--vmstat+jmap+mat对内存泄漏分析

2021-11-25 0:19:29

目录

jmap命令是一个可以输出所有内存中对象的工具,甚至可以将VM 中的heap,以二进制输出成文本。 

1.修改tomcat堆栈内存后启动服务:vim catalina.sh

 2.通过jmeter对系统施加长时间压力,查看是否有内存泄漏发生. 

 3.htop查看系统状态:yum install -y htop-->htop

4.vmstat查看系统free内存变化:vmstat 1,内存持续减少

 5.压测过程中记录java堆内存信息:

        ps -ef | grep java

        jmap -F -dump:format=b,file=pertestdump.bin pid

6.sz保存二进制文件到本地:

 7.memory analyzer打开堆信息转储文件,找到内存泄漏的类或方法

根据类名查找: 

 1.点击histogram ,在Class Name这一栏输入你要过滤的类名

 2.搜索类名的结果 ,发现这个类有13个对象 ,正常情况找个类只有

        一个对象,所以这个类泄漏了

 3.继续查找是谁使用了这个类 ,一直持有这个类的对象,导致无法释放

        1.排除虚引用

        2.找到被谁持有

         3.结果

         4.找到泄漏原因

结果,发现是CallBackManager类中的sCallBack持有了MemoryLeakActivity的引用

既然找到了原因 ,自己就去查看代码吧

根据包名查看

1.打开histogram ,根据图片步骤选择 Group by package

2.找到自己app包名 ,根据业务逻辑排查 ,大多数情况下一个只有一个实例 ,如果有多的怀疑是不是泄漏

3.使用查看Memory Analyzer查看线程

4.使用Memory Analyzer数据库方式搜索类名,查看该类是否存在异常

5.dominator_tree查看内存占比 ,排查占用内存多的原因 ,把占用内存多的释放掉


jmap命令是一个可以输出所有内存中对象的工具,甚至可以将VM 中的heap,以二进制输出成文本。 

memoryAnalyzer下载:Thank You for Downloading Eclipse | The Eclipse Foundation

 此处以java程序举例:

1.修改tomcat堆栈内存后启动服务:vim catalina.sh

 2.通过jmeter对系统施加长时间压力,查看是否有内存泄漏发生. 

 3.htop查看系统状态:yum install -y htop-->htop

         java进程对cpu%使用率达到375%.

4.vmstat查看系统free内存变化:vmstat 1,内存持续减少

 5.压测过程中记录java堆内存信息:

        ps -ef | grep java

        jmap -F -dump:format=b,file=pertestdump.bin pid

               -dump:生成java堆转储快照.

               -heap:显示java堆详细信息,如使用哪种回收器,参数配置,分代情况等.

                -histo:显示堆中对象统计信息,包括类,实例数量和合计容量.

                -F:当服务端进程对-dump选项没有响应时,可使用这个选项生成dump快照.

                file:生成的二进制文件名(需bin,hprof结尾)

6.sz保存二进制文件到本地:

 7.memory analyzer打开堆信息转储文件

在这里插入图片描述

        Histogram:列出内存中被创建的对象个数及大小.

        Dominator Tree:列出哪个线程,以及线程下面的哪些对象占用的内存空间.

        Top Consumers:图形化展示最大的object.

        Leak Suspects:通过mat自动分析泄漏的原因.

在这里插入图片描述

根据类名查找: 

 1.点击histogram ,在Class Name这一栏输入你要过滤的类名

         class name:java类名.

        objects:类创建的对象个数.

        shallow heap:是shallow heap的总和,也就是该对象被gc之后能回收的内存总和.

 2.搜索类名的结果 ,发现这个类有13个对象 ,正常情况找个类只有

        一个对象,所以这个类泄漏了

在这里插入图片描述

 3.继续查找是谁使用了这个类 ,一直持有这个类的对象,导致无法释放

        1.排除虚引用

在这里插入图片描述

        2.找到被谁持有

在这里插入图片描述

         3.结果

在这里插入图片描述

         4.找到泄漏原因

在这里插入图片描述

在这里插入图片描述

  • 结果,发现是CallBackManager类中的sCallBack持有了MemoryLeakActivity的引用

  • 既然找到了原因 ,自己就去查看代码吧

根据包名查看

1.打开histogram ,根据图片步骤选择 Group by package

2.找到自己app包名 ,根据业务逻辑排查 ,大多数情况下一个只有一个实例 ,如果有多的怀疑是不是泄漏

在这里插入图片描述


3.使用查看Memory Analyzer查看线程


4.使用Memory Analyzer数据库方式搜索类名,查看该类是否存在异常

在这里插入图片描述


5.dominator_tree查看内存占比 ,排查占用内存多的原因 ,把占用内存多的释放掉