MAT工具定位分析Java堆内存泄漏问题方法

MAT工具定位分析Java堆内存泄漏问题方法

一、引言

生产环境系统发生突然的服务器宕机,两台服务器分别部署了同一套做了负载均衡,但依旧在前后一个小时之差分别宕机,观察其分别产出的log文件得到两个服务器报错的代码位置不一样,还有老年代内存接近上限,该系统的内存分配为最大10G,所以推测应该是某个功能出现内存溢出导致系统宕机。

因为没有在启动命令中加入-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=heapdump.hprof 所以只能在后续重启系统后手动dump下来,建议正式环境的系统启动命令中加入该参数。

二、MAT概述与安装

MAT,全称Memory Analysis Tools,是一款分析Java堆内存的工具,可以快速定位到堆内泄漏问题。该工具提供了两种使用方式,一种是插件版,可以安装到Eclipse使用,另一种是独立版,可以直接解压使用。

我把独立版MAT安装包放到了网盘上,方便直接下载------------

链接:pan.baidu.com/s/10Adz1aqF...

提取码:rkh4

独立版解压后,其内部文件是这样的------

这里有一个MemoryAnalyzer.ini文件,里面有一个Xmx参数,默认是-Xmx1024m,这代表MAT的最大内存大小,根据具体分析的dump文件大小来做适当调整。

点击MemoryAnalyzer.exe,启动完成后,即可以使用它来检查定位内存泄漏相关的问题了。

三、使用MAT分析

我们将这个heapdump.hprof文件导入到MAT里。启动MAT,点击File,选择Open Heap Dump,然后选择对应的hprof文件,在弹框中选择第一个。

Overview主页面显示应用程序内存使用情况的概览,中间的饼图按retained size来显示最大的对象。注意一点是,在MAT中,会有两种大小表示,一个是Retained size,还有一个是Shallow Size,那么,两者有什么区别呢?

  • Shallow Size:表示对象自身占用的内存大小,不包括它引用的对象。
  • Retained size:当前对象内存大小+当前对象直接或间接引用的对象大小,全部的总和,简单理解,就是当前对象被GC后,总共能释放的内存大小。

1.Details显示的是dump文件的情况,表示堆大小为525MB,有22.8k个class,3.5m个Object,2.2k个类加载器等;

2.功能视图模块;

3.报表模块;

我比较喜欢用Actions的Histogram视图和Reports的Leak Suspects报表,Histogram视图是以类为维度来显示其实例数和每个类的使用内存量,可以协助我们查询哪些类对象占用较大内存;Leak Suspects则可以协助分析内存泄漏的原因所在。

- Histogram视图

以Class Name为维度,分别展示各个类的对象数量,Shallow Size,Retained size。默认内存大小是没有显示单位,但用的byte为单位,可以通过Window->Preferences->Memory Analyzer勾选图中的选项,重新打开Histogram视图即可换算成MB、KB等

通过对Retained size倒序排序发现前三位和文件流有关,第四位和tomcat请求有关,怀疑是一个文件处理程序因为请求量上来了,导致内存堆积,最终导致OOM。对第一名右击会有以下选项

使用List Object可以查看对象引用关系,这里查看引用功能,包括本对象引用外部对象with outgoing references与外部对象引用本对象with incoming references。

此处with outgoing references看不出什么,选择with incoming references并按照Retained Heap倒序。

可以发现大多数数组被标记了EExif.MMJFIF,这表明它可能是一个 JPEG 图像文件的开始的标记,所以我们也可以猜测是对图片处理产生了内存堆积,到此基本上可以联想到问题大概率就是最近新上的给上传的图片进行水印处理的功能设计不合理。

- Leak Suspects报表

Leak Suspects报表很直观地展现了一个饼图,图中颜色深的部分表示可能存在内存泄漏的嫌疑。每一个模块都有对应的详情信息。点击See stacktrace得到下面日志信息

可以直观找到对应有问题的代码位置,进一步证明了之前猜测的准确性。

内容来源:

www.cnblogs.com/zhujiqian/p...

相关推荐
章豪Mrrey nical16 小时前
前后端分离工作详解Detailed Explanation of Frontend-Backend Separation Work
后端·前端框架·状态模式
派大鑫wink17 小时前
【JAVA学习日志】SpringBoot 参数配置:从基础到实战,解锁灵活配置新姿势
java·spring boot·后端
程序员爱钓鱼18 小时前
Node.js 编程实战:文件读写操作
前端·后端·node.js
xUxIAOrUIII18 小时前
【Spring Boot】控制器Controller方法
java·spring boot·后端
Dolphin_Home18 小时前
从理论到实战:图结构在仓库关联业务中的落地(小白→中级,附完整代码)
java·spring boot·后端·spring cloud·database·广度优先·图搜索算法
zfj32118 小时前
go为什么设计成源码依赖,而不是二进制依赖
开发语言·后端·golang
weixin_4624462318 小时前
使用 Go 实现 SSE 流式推送 + 打字机效果(模拟 Coze Chat)
开发语言·后端·golang
JIngJaneIL18 小时前
基于springboot + vue古城景区管理系统(源码+数据库+文档)
java·开发语言·前端·数据库·vue.js·spring boot·后端
小信啊啊19 小时前
Go语言切片slice
开发语言·后端·golang
Victor35620 小时前
Netty(20)如何实现基于Netty的WebSocket服务器?
后端