34-内存泄露MAT工具看本文就够了

简介: 通过本篇文章的讲解,大家对于MAT工具的使用有了一定的理解和参考,后续遇到内存泄露、内存卡顿、大对象数据分析都可以直接通过MAT精准确定,更好的优化我们的项目。

一. 简介

Eclipse Memory Analyzer是一个快速且功能丰富的Java堆分析器,可帮助您查找内存泄漏并减少内存消耗。使用Memory Analyzer分析具有数亿个对象的高效堆转储,快速计算对象的保留大小,查看谁阻止垃圾收集器收集对象,运行报告以自动提取泄漏嫌疑者。

通过MAT工具,可以做以下几方面的事儿:

  • 找到最大的对象,因为 MAT 提供了合理的累积大小(retained size)
  • 探索对象图,包括入站和出站引用
  • 计算从GC Roots 到有趣对象的路径
  • 查找内存浪费,如冗余 String 对象、空集合对象等...

二.下载地址

https://www.eclipse.org/mat/downloads.php

目前绝大多数开发工具都已经使用IDEA了,因此大家下载独立的MAT即可,注意:独立的MAT运行需要在JDK11及以上的环境。

三.Heap Dump

首先了解下Heap Dump,它也叫堆转储文件,是java进程在某个时间内的快照。它在触发快照的时候保存了很多信息:java对象和类信息。通常情况下,在写入堆转储之前会触发完整的 GC,因此它包含有关剩余对象的信息。

Memory Analyzer 能够处理来自各种平台的 HPROF 二进制堆转储、IBM 系统转储(旧版本需要预处理)和 IBM 便携式堆转储 (PHD)。

在Heap Dump中能得到的信息包括:(以下摘自官网)

Typical information which can be found in heap dumps (depending on the heap dump type):

  • All Objects

    Class, fields, primitive values and references

  • All Classes

    Classloader, name, super class, static fields

  • Garbage Collection Roots

    Objects defined to be reachable by the JVM

  • Thread Stacks and Local Variables

    The call-stacks of threads at the moment of the snapshot, and per-frame information about local objects

这里给大家翻译一下为:

可以在堆转储中找到的典型信息(取决于堆转储类型):

  • 所有对象
    类、字段、原始值和引用

  • All Classes

    类加载器、名称、超类、静态字段

  • 垃圾收集根对象GC Roots
    定义为可由 JVM 访问的对象(比如:局部变量和类静态变量)

  • 线程栈和局部变量
    快照时刻线程的调用堆栈,以及有关本地对象的每帧信息

四.怎样获取Dump

Dump文件的格式为:HPROF,内存分析器可以处理HPROF 二进制格式的堆转储

那么我们可以从以下几方面来获取Dump文件:

  • Non-interactive 被动获取:

    通过OOM获取,即在OutOfMemoryError后获取一份HPROF二进制Heap Dump文件,可以在jvm里添加参数:(除非真正发生 OOM,否则不涉及任何开销)

    -XX:+HeapDumpOnOutOfMemoryError
    

    这个参数对于生产系统来说是必须的,因为它通常是进一步分析内存泄露问题的唯一方法。

    默认情况下,堆转储将在 JVM 的“当前目录”中生成。它可以使用-XX:HeapDumpPath=显式重定向,例如-XX:HeapDumpPath=/disk2/dumps。请注意,转储文件可能很大,可达千兆字节,因此请确保目标文件系统有足够的空间。

  • Interactive 主动获取

    1. 在虚拟机中添加参数如下,然后在Ctrl+Break组合键即可获取一份Heap Dump:

      -XX:+HeapDumpOnCtrlBreak
      
  1. 通过 jmap 工具生成,在命令行中输入:

    jmap -dump:format=b file=<文件名XX.hprof> <pid>
    
  2. Sun JConsole:启动 jconsole.exe 并在 HotSpotDiagnostic MBean 上调用操作 dumpHeap()

  3. 使用Memory Analyzer Tools的File -> Acquire Heap Dump功能


图形化界面操作,直接选择想要dump的pid进程,设置存放文件的路径即可。

五.MAT使用

准备一份dump文件,通过MAT工具进行打开,在选好文件后,会让你选一下报告类型,默认是内存泄漏探测报告,没有什么特殊情况下,选它就可以了:

内存泄漏可疑点(Leak Suspects)

进入MAT后会展示内存泄漏可疑点在内存中的分布情况,还会列出具体的类,如果是自己的代码,基本上一眼大概就能定位到某些业务,如果还不能肯定,也没关系,接下来还有很多功能可以辅助分析

上图中Problem Suspect1 即代表可能出现内存泄露的问题分析:

The thread java.lang.Thread @ 0xff626d38 main keeps local variables with total size 7,293,920 (89.25%) bytes.

​ 在线程的main中持续引用本地变量达到了 7.3M的内存,占用堆内存89.25%

The memory is accumulated in one instance of java.lang.Object[], loaded by , which occupies 7,292,936 (89.24%) bytes.

​ 内存累积在一个“java.lang.Object[]”实例中,由“”加载,占用7,292,936 (89.24%)字节。说明的非常清晰,这个数组占据了大量的内存。

那么这个数组里到底是什么东西呢?

在上图中的左下角大家看到有一个 Details,大家点进去即可看到详细的说明:

通过Details我们可以看到,在主线程的下方引用了一个 java.util.ArrayList, 这里面是一个java.lang.Object[]数组,通过这里我们既可以清楚到底是什么对象占用了过大的内存,所以MAT分析内存是非常方便的。

六.追踪线程执行堆栈,找到问题代码

一旦发现在某个线程执行过程中创建了大量对象之后,就可以尝试找这个线程到底执行了哪些代码才创建了这些对象,我们可以点击下图中的“See stacktrace”

点击进去后即准确找到了发生问题的代码行数:

这里我们贴出对应的源代码,其实非常简单,如下:

代码问题就出现在了第10行,list添加元素这儿。

七. Histogram

刚才我们是在Leak Suspects中进行分析的,另外我们还可以打开一个非常常用的工具:Histogram

点击进去:

这里每一列的参数做一个解释:

  • Class Name : 类名称,java类名
  • Objects : 类的对象的数量,这个对象被创建了多少个
  • Shallow Heap :一个对象内存的消耗大小,不包含对其他对象的引用
  • Retained Heap :是shallow Heap的总和,也就是该对象被GC之后所能回收到内存的总和

可以看到Object[]这个数组就占据了7.4MB.

在某一项上右键打开菜单选择 list objects ->with incoming refs 将列出该类的实例:

大家可以发现通过这种方式也是能直观找到我们的大对象到底是什么。

好了,相信通过本篇文章的讲解,大家对于MAT工具的使用有了一定的理解和参考,后续遇到内存泄露、内存卡顿、大对象数据分析都可以直接通过MAT精准确定,更好的优化我们的项目。

目录
相关文章
|
6月前
|
监控 NoSQL Linux
深入Linux内存泄漏排查:Valgrind与系统工具的联合应用
深入Linux内存泄漏排查:Valgrind与系统工具的联合应用
875 0
|
21天前
|
Web App开发 JavaScript 前端开发
使用 Chrome 浏览器的内存分析工具来检测 JavaScript 中的内存泄漏
【10月更文挑战第25天】利用 Chrome 浏览器的内存分析工具,可以较为准确地检测 JavaScript 中的内存泄漏问题,并帮助我们找出潜在的泄漏点,以便采取相应的解决措施。
135 9
|
1月前
|
存储 监控 算法
JVM调优深度剖析:内存模型、垃圾收集、工具与实战
【10月更文挑战第9天】在Java开发领域,Java虚拟机(JVM)的性能调优是构建高性能、高并发系统不可或缺的一部分。作为一名资深架构师,深入理解JVM的内存模型、垃圾收集机制、调优工具及其实现原理,对于提升系统的整体性能和稳定性至关重要。本文将深入探讨这些内容,并提供针对单机几十万并发系统的JVM调优策略和Java代码示例。
51 2
|
5月前
|
存储 Linux Android开发
Volatility3内存取证工具安装及入门在Linux下的安装教程
Volatility 是一个完全开源的工具,用于从内存 (RAM) 样本中提取数字工件。支持Windows,Linux,MaC,Android等多类型操作系统系统的内存取证。针对竞赛这块(CTF、技能大赛等)基本上都是用在Misc方向的取证题上面,很多没有听说过或者不会用这款工具的同学在打比赛的时候就很难受。以前很多赛项都是使用vol2.6都可以完成,但是由于操作系统更新,部分系统2.6已经不支持了,如:Win10 等镜像,而Volatility3是支持这些新版本操作系统的。
|
3月前
|
NoSQL Java 测试技术
Golang内存分析工具gctrace和pprof实战
文章详细介绍了Golang的两个内存分析工具gctrace和pprof的使用方法,通过实例分析展示了如何通过gctrace跟踪GC的不同阶段耗时与内存量对比,以及如何使用pprof进行内存分析和调优。
84 0
Golang内存分析工具gctrace和pprof实战
|
3月前
|
监控 Java
JAVA性能优化- IntelliJ插件:java内存分析工具(JProfiler)
JAVA性能优化- IntelliJ插件:java内存分析工具(JProfiler)
148 0
|
4月前
|
监控 Java 开发者
Java面试题:如何使用JVM工具(如jconsole, jstack, jmap)来分析内存使用情况?
Java面试题:如何使用JVM工具(如jconsole, jstack, jmap)来分析内存使用情况?
203 2
|
5月前
|
C++
内存泄漏检查工具下载(vld)
内存泄漏检查工具下载(vld)
|
4月前
|
监控 算法 Java
怎么用JDK自带工具进行JVM内存分析
JVM内存分析工具,如`jps`、`jcmd`、`jstat`、`jstack`和`jmap`,是诊断和优化Java应用的关键工具。`jps`列出Java进程,`jcmd`执行诊断任务,如查看JVM参数和线程堆栈,`jstat`监控内存和GC,`jstack`生成线程堆栈信息,而`jmap`则用于生成堆转储文件。这些工具帮助排查内存泄漏、优化内存配置、性能调优和异常分析。例如,`jmap -dump:file=heapdump.hprof &lt;PID&gt;`生成堆转储文件,之后可以用Eclipse Memory Analyzer (MAT)等工具分析。
|
4月前
|
安全 Java 调度
Java面试题:Java内存优化、多线程安全与并发框架实战,如何在Java应用中实现内存优化?在多线程环境下,如何保证数据的线程安全?使用Java并发工具包中的哪些工具可以帮助解决并发问题?
Java面试题:Java内存优化、多线程安全与并发框架实战,如何在Java应用中实现内存优化?在多线程环境下,如何保证数据的线程安全?使用Java并发工具包中的哪些工具可以帮助解决并发问题?
63 0