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

原创/朱季谦

一、MAT概述与安装

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

我把独立版MAT安装包放到了网盘上,方便直接下载————
链接:百度网盘 请输入提取码
提取码:rhb5

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

image

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

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

image

二、内存泄漏案例分析

下面,我会结合一个小案例来分享MAT的使用。

首先,用IDEA建立一个测试类——

public class example {public static void main(String[] args)  {List<User> list=new ArrayList<>();while (true){list.add(new User());}}
}class User {private String name="demo";public User() {}
}

给这个测试类设置虚拟机参数,设置如:-Xms2m -Xmx2m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=D:/local_system/git/demo/heapdump.hprof

这几个参数的意义是:

-Xms2m -Xmx2m:堆最小内存为2M,最大内存为2M。这里没有显示设置新生代大小,它会自动分配新生代大小,分配完剩下的,就是老年代大小了。

-XX:+HeapDumpOnOutOfMemoryError:指发生内存溢出的时候,会自动生成一个二进制的堆快照文件,这个快照文件以.hprof后缀结尾。用MAT分析堆内存信息,就是利用这个.hprof文件。除了可以设置相应的虚拟机参数外,还可以通过jmap指令来获取到某个进程的堆快照文件,执行指令格式是:

jmap -dump:format=b,file=<dumpfile.hprof> <pid>

例如:jmap -dump:format=b,file=20210618.dump 7132,那么,这里20210618.dump就是自定义的dump堆转储文件名字,而7132是进程ID。只是使用jmap指令可能有一点不好的地方是,内存溢出是某个时间点发生的事情,jmap指令去获取到dump文件,存在时间差问题。而HeapDumpOnOutOfMemoryError则是在发生内存溢出时,同时生成的,故而会更准确些。

-XX:HeapDumpPath=D:/local_system/git/demo/heapdump.hprof:内存溢出产生的堆快照自动存储路径,可以自定义指定路径。

其实,在实际生产环境里,除了这些基本参数外,还有其他的JVM参数,这些参数都是用来调优的重点所在。

这里暂且以这些参数做实验,在运行IDEA时,可以将这些参数设置在IDEA的“Run/Debug Configurations”弹出框的VM options输入框里,如下截图所示——

image

按照以上方式设置好后,就可以运行该案例代码了,运行一会儿后,就会出现以下提示——

image

这表明,该代码已经发生内存溢出了,即ArrayList存储的对象大小已经超过堆内存,导致无法进行垃圾回收,也就是出现内存泄漏,进而导致内存溢出。当然,在本地是可以看到这么简单的异常提示的,但是在线上服务器上,就没有那么明显的内存溢出提示,就需要获取到产生的堆快照dump文件,然后再进一步分析堆快照信息。

三、使用MAT分析堆转储dump文件

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

在弹出框处,选择Leak Suspects Report,这是指内存泄漏报告——

image

点击Finish后,展示Overview主页面如下——

image

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

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

1.Details显示的是dump文件的情况,表示堆大小为1.1MB,有516个class,40.2k个Object,3个类加载器等;

2.功能视图模块;

3.报表模块;

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

- Histogram视图

image

以Class Name为维度,分别展示各个类的对象数量,Shallow Size,Retained size。这里有一个疑惑是,Shallow Size和Retained size没有显示是以什么为单位的,它默认是以byte为单位的,若要显示地让单位展示出来,可以这样设置,点击Window->Preferences

image

选择最后一项,点击Apply and Close——

image

再重新打开Histogram视图,就会生效了,单位就显示出来了——

image

根据这个Histogram视图,我们可以发现,com.example.demo.User数量和占用内存大小都比较高,同时说明了该User对象一直没有被GC回收掉,这时,可以右击,弹出框有以下一些菜单选项——

image

  • List objects

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

    1. with outgoing references

      使用该功能,可以查看对象内部都引用了哪些外部对象,例如,这里的User,其引用外部对象情况如下:

      image

      对照这个案例的代码,可见,在创建这个User对象时,内部属性name就会指向一个字符串地址,换言之,该User对象内部有个引用指向了一个name字符串地址。

      image

    2. with incoming references

    ​ 使用该功能,可以查看该对象都被哪些外部所引用了——

    image

​ 在案例代码当中,是以list.add(User)来不断存储User对象的,如截图所示,通过MAT可确定,存在一个ArrayList集合一直引用该User对象。

在实际开发当中,一个对象可能引用了诸多其他外部对象或者被诸多外部对象所引用,若一直引用着,说明某个对象一直存在GC ROOT可达的情况,反过来就意味着,该被引用的对象一直无法被GC回收处理,那么就可能会一直存在堆内存里,进而造成内存泄漏的情况。

  • Merge Shortest Paths to GC Roots->exclude all phantom/weak/soft etc. references

image

排除其他引用,只观察GC路径上强引用的对象,所观察到的,都是仍存活的对象。

除此之外,Histogram视图仍有其他功能,后期在学习过程当中,不断进行完善。

- Leak Suspects报表

image

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

这里拿模块a来讲解,其详情部分有一句话很关键:The memory is accumulated in one instance of "java.lang.Object[]", loaded by "", which occupies 617.55 KB (52.54%) bytes.The stacktrace of this Thread is available. See stacktrace. See stacktrace with involved local variables.

这句话翻译过来就是,内存累积在一个“java.lang.Object[]”实例中,由“”加载,占用617.55 KB(52.54%)字节。此线程的堆栈跟踪可用。请参见stacktrace。请参阅包含局部变量的stacktrace。

点击stacktrace,进入到一个页面,可以看到日志信息——

image

在这里,从下往上看异常信息,可以快速定位内存泄漏地方出现在哪个类方法里的哪行代码。

我很喜欢使用这个功能,通过获取线上堆转储文件,便可以通过Leak Suspects定位到内存泄漏快速定位在哪一行代码。

欢迎关注博主,后续会发更多原创总结。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/143700.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【python 生成器 面试必备】yield关键字,协程必知必会系列文章--自己控制程序调度,体验做上帝的感觉 1

python生成器系列文章目录 第一章 yield — Python (Part I) 文章目录 python生成器系列文章目录前言1. Generator Function 生成器函数2.并发和并行&#xff0c;抢占式和协作式2.Let’s implement Producer/Consumer pattern using subroutine: 生成器的状态 generator’s st…

ESP32网络开发实例-BME280传感器数据保存到InfluxDB时序数据库

BME280传感器数据保存到InfluxDB时序数据库 文章目录 BME280传感器数据保存到InfluxDB时序数据库1、BM280和InfluxDB介绍2、软件准备3、硬件准备4、代码实现在本文中,将详细介绍如何将BME280传感器数据上传到InfluxDB中,方便后期数据处理。 1、BM280和InfluxDB介绍 InfluxDB…

tracert命令

前言&#xff1a;今天在阅读“Web性能权威指南”这本书的时候&#xff0c;发现 tracert 这个命令挺有意思的&#xff0c;在分析网络性能瓶颈的时候也能使用的到&#xff0c;在此就小记一笔以备后用。 1&#xff1a;作用 tracert 是一个简单的网络诊断工具&#xff0c;可以列出…

如何在Windows 10中进行屏幕截图

本文介绍如何在Windows 10中捕获屏幕截图&#xff0c;包括使用键盘组合、使用Snipping Tool、Snipp&Sketch Tool或Windows游戏栏。 使用打印屏幕在Windows 10中捕获屏幕截图 在Windows 10中捕获屏幕截图的最简单方法是按下键盘上的PrtScWindows键盘组合。你将看到屏幕短暂…

python自动化第一篇—— 带图文的execl的自动化合并

简述 最近接到一个需求&#xff0c;需要为公司里的一个部门提供一个文件上传自动化合并的系统&#xff0c;以供用户稽核&#xff0c;谈到自动化&#xff0c;肯定是选择python&#xff0c;毕竟python的轮子多。比较了市面上几个用得多的python库&#xff0c;我最终选择了xlwings…

将按键放到输入框内:

如何将将Button放到输入框内&#xff1f; 效果图&#xff1a; 步骤如下&#xff1a; button 外围用template 包裹一层 <template #suffix v-if"row.WorkerRole TPM"> <el-inputtype"text"v-model"row.JobNumber"placeholder"…

云原生下GIS服务规划与设计

作者&#xff1a;lisong 目录 背景云原生环境下GIS服务的相关概念GIS服务在云原生环境下的规划调度策略GIS服务在云原生环境下的调度手段GIS服务在云原生环境下的服务规划调度实践 背景 作为云原生GIS系统管理人员&#xff0c;在面对新建的云GIS系统时&#xff0c;通常需要应对…

使用 PYTORCH 进行图像风格迁移

一、介绍 本教程介绍如何实现 由 Leon A. Gatys、Alexander S. Ecker 和 Matthias Bethge 开发的神经风格算法。神经风格或神经传输允许您拍摄图像并以新的艺术风格再现它。该算法采用三幅图像&#xff0c;即输入图像、内容图像和风格图像&#xff0c;并将输入更改为类似于内容…

Python框架篇(1):FastApi-快速入门

1.介绍 前言: 不管学什么语言&#xff0c;都应该至少掌握一个框架&#xff0c;方面我们后续&#xff0c;进行服务部署、服务对外支持等; 1.1 官网介绍 下面是来自FastAPI官网的介绍: FastAPI 是一个用于构建 API 的现代、快速&#xff08;高性能&#xff09;的 web 框架&#…

为忙碌的软件工程师精心准备的编码面试准备材料,超过 100,000 人受益!

这是一个针对技术面试准备的手册。它收集了大量的面试问题和答案&#xff0c;涵盖了算法、系统设计、前端等主题&#xff0c;并且还在不断更新和完善中。 这个项目是“Tech Interview Handbook”&#xff0c;解决了求职者在技术面试中遇到的各种难题&#xff0c;帮助他们更好地…

C++ Qt 学习(六):Qt http 编程

1. http 基础 HTTP 基础教程C Web 框架 drogonoatpp 2. C Qt 用户登录、注册功能实现 login_register.h #pragma once#include <QtWidgets/QDialog> #include "ui_login_register.h" #include <QNetworkReply>class login_register : public QDialog…

开源网安受邀参加网络空间安全合作与发展论坛,为软件开发安全建设献计献策

​11月10日&#xff0c;在广西南宁举办的“2023网络空间安全合作与发展论坛”圆满结束。论坛在中国兵工学会的指导下&#xff0c;以“凝聚网络空间安全学术智慧&#xff0c;赋能数字经济时代四链融合”为主题&#xff0c;邀请了多位专家及企业代表共探讨网络安全发展与数字经济…

《网络协议》05. 网络通信安全 · 密码技术

title: 《网络协议》05. 网络通信安全 密码技术 date: 2022-09-10 15:16:15 updated: 2023-11-12 07:03:52 categories: 学习记录&#xff1a;网络协议 excerpt: 网络通信安全&#xff08;ARP 欺骗&#xff0c;DoS & DDoS&#xff0c;SYN 洪水攻击&#xff0c;LAND 攻击&a…

MVC使用的设计模式

MVC使用的设计模式 一、背景 MVC模式是"Model-View-Controller"的缩写&#xff0c;中文翻译为"模式-视图-控制器"。MVC应用程序总是由这三个部分组成。Event(事件)导致Controller改变Model或View&#xff0c;或者同时改变两者。只要Controller改变了Model…

5个用于地理空间数据分析的Python包

大家好&#xff0c;地理空间数据分析在城市规划、环境研究、农业和交通等行业中至关重要。不断增长的需求导致Python包在各种地理数据分析要求上的使用增加&#xff0c;例如分析气候模式、研究城市发展或跟踪疾病传播等&#xff0c;评估和选择具有快速处理、修改和可视化能力的…

IDEA安装配置SceneBuilder

1、下载 SceneBuilder 地址&#xff1a; Scene Builder - Gluon ​​​​​​​ Scene Builder | JavaFX中文官方网站 选择符合自己系统版本&#xff0c;JAVA版本的下载 2、安装SceneBuilder 执行下载的 SceneBuilder 安装程序&#xff0c;并按照安装向导的指示进行…

高防IP可以抵御哪些恶意攻击

高防IP协议可以隐藏用户的站点&#xff0c;使得攻击者无法发现恶意攻击的目标网络资源&#xff0c;从而提高了源站的安全性。能够有效抵御常见的恶意攻击类型ICMPFlood、UDPFlood、 TCPFlood、SYNFlood、ACKFlood等&#xff0c;帮助游戏、金 融、电子商务、互联网、政企等行业抵…

实际使用Elasticdump工具对Elasticsearch集群进行数据备份和数据还原

文/朱季谦 目录一、Elasticdump工具介绍二、Elasticdump工具安装三、Elasticdump工具使用 最近在开发当中做了一些涉及到Elasticsearch映射结构及数据导出导入的工作&#xff0c;怕以后会把这过程忘记&#xff0c;可谓好记性不如烂笔头&#xff0c;故而记录成一篇博文。 玩El…

钉钉统计部门个人请假次数go

前言 最近小组需要统计部门各种请假次数&#xff0c;写了一个方法&#xff0c;第一次实战中用到递归函数&#xff0c;简单记录一下。 效果展示 这些数据不需要返回json&#xff0c;这里这样是为了方便测试。可以通过这些数据完成其它的操作。 功能实现 钉钉服务端调试工具A…

Java主流分布式解决方案多场景设计与实战

Java的主流分布式解决方案的设计和实战涉及到多个场景&#xff0c;包括但不限于以下几点&#xff1a; 分布式缓存&#xff1a;在Java的分布式系统中&#xff0c;缓存是非常重要的一部分。常用的分布式缓存技术包括Redis、EhCache等。这些缓存技术可以用来提高系统的性能和响应…