java内存性能优化工具Mat

1.MAT(Memory Analyzer Tool)工具是一款功能强大的]ava堆内存分析器。可以用于查找内存泄漏以及查看内存消耗情况。MAT是基于Eclipse开发的,不仅可以单独使用,还可以作为插件的形式嵌入在Eclipse中使用。是一款免费的性能分析工具,使用起来非常方便。

2.下载地址

https://eclipse.dev/mat/download/

我这边电脑的系统是window系统,jdk版本是1.8,下载时应选择对应的版本下载

3.安装

双击启动MemoryAnalyzer.exe启动

如果启动报错,出现Incompatible JVM 弹窗时,下载弹窗中指定的jdk版本,不需要安装解压后在MemoryAnalyzer.ini 中通过加入以下内容加入指定jdk的地址

-vm

D:/java/jdk1.8.0_211/bin/javaw.exe

4.使用

点击左上角file,选择所要打开的分析文件

如果堆dump文件较大、使用MAT打开的时候总是抛出 Java Heap Error

解决办法:

找到MAT的安装目录,找到MemoryAnalyzer.ini 修改其中的-Xmx即可

5.获取dump文件

通过top -c(然后按Shift+M按内存排序)命令找到占用内存大的java进程,通过以下命令生成dump文件

  • jmap -dump:format=b,file=oom.hprof 进程ID

通常情况下,在生产环境中使用jmap命令生成Heap dump文件时,建议把生成的文件下载到本地进行分析,以减少对生产环境的干扰。另外,在生成Heap dump文件时,一定要确保Java应用程序正常运行,否则可能会导致生成的文件不完整或者无法正确解析。

二、MAT工具排查分析

1.使用MAT定位问题

定位问题方式一:

现在有一个OOM后得到的堆转储文件 oom.hprof,现在要使用 MAT 的直方图支配树线程栈OQL 等功能来分析此次 OOM 的原因。

首先,用 MAT 打开后先进入的是概览信息界面,可以看到整个堆是 51MB:

那么,这 51MB 都是什么对象呢?

如图所示,工具栏的第二个按钮可以打开直方图,直方图按照类型进行分组,列出了每个类有多少个实例,以及占用的内存。可以看到,char[]字节数组占用内存最多,对象数量也很多,结合第二位的 byte[] 字节数组数量也很多,大概可以猜出程序可能是char[]和byte[]作为实际数据存储占满了内存,导致 OOM。

char[]上点击右键,选择 List objects->with incoming references,就可以列出所有的 char[]实例,以及每个 char[]的整个引用关系链:

  • Shallow Heap(浅堆)指对象自身占用内存的大小,包括对象头和成员变量(但不包括成员变量的值)
  • Retained Heap(深堆/保留堆)指对象被回收后,所有因引用关系被释放的对象所占内存总和。

找到Shallow Heap占用最大的一个 char[]展开,如下图所示:

可以大概知道我这个项目中write占用过多的内存,但是还是不能具体到那个具体的程序。

定位问题2:

点击工具栏中第三个按钮(下图左上角的红框所示)进入支配树界面。这个界面会按照对象的 Retained Heap 倒序直接列出占用内存最大的对象。

从上面的具体信息中可以看到序列化,缓存,数据库初始化所占用的内存较大,但是还是不能定位到具体的程序。

定位问题3:

点击工具栏的第五个按钮(下图红色框所示)。打开线程视图

通过以上信息可以看出我的程序中产生了很多定时程序的线程,从而占用了大量内存。

然后可以通过搜索查看引用的对象

点击工具栏的第四个按钮(如下图红框所示),来到 OQL 界面。在这个界面,我们可以使用类似 SQL 的语法,在 dump 中搜索数据(你可以直接在 MAT 帮助菜单搜索 OQL Syntax,来查看 OQL 的详细语法)。

sql:

  • select * from org.apache.tomcat.util.threads.TaskThread

点击下图中红色叹号按钮,运行上记sql,查找对象

定位问题4:

点击工具栏的第一个按钮(如下图红框所示),进入Leak Suspects界面

Leak Suspects 是 Eclipse Memory Analyzer (MAT) 工具的核心功能之一,用于快速定位 Java 堆转储文件中的内存泄漏嫌疑对象。

点击Details,查看详情

通过上述信息可以看出我的项目中定时任务占用了大量内存

通过查找代码,发现我启动了很多的定时任务

通过分析优化掉不需要的定时任务,可以释放一些内存。

相关推荐
Ray Liang1 小时前
用六边形架构与整洁架构对比是伪命题?
java·python·c#·架构设计
Java水解1 小时前
Java 中间件:Dubbo 服务降级(Mock 机制)
java·后端
SimonKing6 小时前
OpenCode AI辅助编程,不一样的编程思路,不写一行代码
java·后端·程序员
FastBean6 小时前
Jackson View Extension Spring Boot Starter
java·后端
Seven977 小时前
剑指offer-79、最⻓不含重复字符的⼦字符串
java
皮皮林55116 小时前
Java性能调优黑科技!1行代码实现毫秒级耗时追踪,效率飙升300%!
java
冰_河16 小时前
QPS从300到3100:我靠一行代码让接口性能暴涨10倍,系统性能原地起飞!!
java·后端·性能优化
桦说编程19 小时前
从 ForkJoinPool 的 Compensate 看并发框架的线程补偿思想
java·后端·源码阅读
躺平大鹅21 小时前
Java面向对象入门(类与对象,新手秒懂)
java