JVM系列(二十九) JVM调优实战-MAT内存分析Dump-LeakSuspects内存泄漏定位

1,245 阅读3分钟

MAT内存分析Dump-LeakSuspects内存泄漏定位

前面我们讲解了MAT内存分析工具,打开Dump文件后,找到Leak Suspects内存泄漏检测点,然后打开系统概览,我们分析了系统概览可以帮助我们干什么,解析什么,今天我们讲解 Leaks 内存泄漏分析

  • OverView 饼状图,显示堆内存 Total 68.2M 堆一共68M
  • Problem Suspect 1 内存泄漏排查点, 有可能发生内存泄漏的地方,内存大小占用 58.1M
  • Remainder 内存正常的地方

image.png

下面我们看下 Leaks 下面的 Problem Suspect 1 内存泄漏排查点1, 看下可以获取或者定位哪些问题

1.Leak Suspects 内存泄漏点排查 Problem Suspect 1

Leak Suspects内存泄漏分析, 可以看到有很多的线程 比如 http-nio-8078-exec-4,然后占用内存100296 bytes,占用内存比例

Leak Suspects

51 instances of **"org.apache.tomcat.util.threads.TaskThread"**, loaded by **"sun.misc.Launcher$AppClassLoader @ 0xf9c1db90"** occupy **60,956,752 (85.23%)** bytes.

Biggest instances:

-   org.apache.tomcat.util.threads.TaskThread @ 0xfa59de78 http-nio-8078-exec-11 - 2,100,400 (2.94%) bytes.
-   org.apache.tomcat.util.threads.TaskThread @ 0xfa4c0b68 http-nio-8078-exec-9 - 2,100,296 (2.94%) bytes.

image.png

我们看下 内存泄漏排查 可以获取哪些信息

  • 存在51个对象 51 instances,都是TaskThread 对象
  • 这些对象占用了 60,956,752 bytes,占堆内存的 85.23%比例
  • 大对象信息如下 TaskThread @ 0xfa59de78 http-nio-8078-exec-11 - 2
  • 大对象TaskThread 占用2,100,400 bytes,占用堆内存2.94%的比例

可以从饼图的 Problem Suspect 1点击,分析 入引用及出引用

image.png

2.查看详情 Detail信息

在Problem Suspects 1 的最下面有个Details 详情信息

点击Details 查看内存泄漏排查点的详细信息,出现四个选项

  • Biggest Instances (Overivew) 最多的实例信息 概览信息
  • Biggest Instances 具体信息
  • Reference Pattern 展示Class 类, 对象Objects数量,Shallow Heap 对象的浅堆,对象本身大小6528

image.png image.png

2.1 点击 Biggest Instances (Overivew)

点击 Biggest Instances (Overivew) 概览信息,展示所有的大对象的实例信息, 你可以分析该实例,包括实例的 incoming reference 入引用,该对象被谁引用,outgoing reference 出引用,该对象引用了谁,看里面的内容

image.png

2.2 点击 Biggest Instances 定位内存泄漏位置

点击 Biggest Instances ,我可以看到具体的 对象实例信息,下面我们看如何通过实例信息,定位内存泄漏点

点击后, 如下图出现很多的 线程信息及 Shallow Heap, Retained Heap

image.png

前面我们已经介绍过 Shallow Heap 和 Retained Heap

  • Shallow Heap 浅堆
    • 浅堆的意思是是说当前对象本身自身的大小(一个对象由对象头 和 该对象实例数据 及对象头对齐填充信息构成)
  • Retained Heap 深堆
    • 深堆是一种统计的结果,统计的就是该对象及对象引用信息,如果当前对象被回收了,那么它及它的引用在一起,可以一共回收掉多少内存

我们点击 线程信息,进行内存泄漏定位, 选择List Objects, 然后选择 Outgoing Reference 找它引用了谁,为什么这么大,到底里面存了啥

image.png

然后点开, 找到自己程序的类信息, 因为别的类加载一般都不会出问题, 最有可能出问题的就是你自己的类信息

image.png

定位到了 TestController 的Test 方法, 也就是我们之前启动程序,用HTTP请求访问的方法

image.png

3.3 点击Reference Pattern

展示对象信息,包括对象Objects数量, 引用的对象的数量, Shallow Heap 对象浅堆该对象本身大小等信息

image.png


至此我们已经能够通过 Leak Suspects 来定位分析出代码的问题,找出内存泄漏的位置解决问题