如何通过MAT排查生产环境服务内存溢出

news/2024/10/22 7:58:09/

前言

前段时间,运维反馈生产环境翻译服务某个节点触发内存告警了。运维在重启节点之前,生成了dump快照,这里介绍下如何使用MAT内存分析工具来排查服务内存高占用问题。

MAT简介

MAT是Memory Analyzer的简称,它是一款功能强大的Java堆内存分析器。可以用于查找内存泄露以及查看内存消耗情况。MAT是基于Eclipse开发的,是一款免费的性能分析工具。读者可以在Eclipse Memory Analyzer Open Source Project | The Eclipse Foundation下载并使用MAT。

问题排查经过

MAT有免安装版本,我在自己电脑windows上直接打开就行

 这里需要注意一下,运维发过来的dump文件大小有8G左右,MAT的默认内存是1024M,直接导入这个8G的dump文件,工具解析了一会就报错了,需要修改下MAT的配置文件,把内存配置调大

 这里直接把1024改成了6024,由于在本地电脑上解析,解析时间有点漫长....,条件允许的话,完全可以在开发或者联调环境Linux服务器上用MAT(有Linux版本)解析,解析完成之后页面如下

 很明显,我们看到了一个大对象集合

 上图可以看到存在一个大的对象集合,并且在图的左下角,有对应的线程名字,我们可以根据这个线程名到日志中取查询下具体哪一个请求导致了这个大对象集合。

 再根据请求对应的traceId,找到请求链路,以及对应的业务数据

 后来发现是某个PPT文档翻译,导致创建了一个大的对象集合,最终占用了接近5G的内存。问题到这里,内存占用的原因就算是找到了,具体PPT翻译的问题,交给开发PPT翻译的同时排查即可。

MAT的其他功能介绍

查看对应线程详情

 如上图所示,可以点击大对象,查找对应的线程详情 ​​​​​​

 还有表格形式

 当然,这里查看Java层面的应用线程,对于虚拟机的系统线程是无法显示的。通过线程的堆栈,还可以查看局部变量的信息。

浅堆和深堆

浅堆(Shallow Heap)和深堆(Retained Heap)是两个非常重要的概念,它们分别表示一个对象结构所占用的内存大小和一个对象被GC回收后,可以真实释放的内存大小。浅堆(Shallow Heap)是指一个对象所消耗的内存。在32位系统中,一个对象引用会占据4个字节,一个int类型会占据4个字节,long型变量会占据8个字节,每个对象头需要占用8个字节。根据堆快照格式不同,对象的大小可能会向8字节进行对齐。以String对象为例,如下图所示,显示了String对象的几个属性。

  • String
    • value:char[]
    • offset:int
    • count:int
    • hash:int

3个int值共占12字节,对象引用占用4字节,对象头8字节,合计24字节。浅堆的大小只与对象的结构有关,与对象的实际内容无关。也就是说,无论字符串的长度有多少,内容是什么,浅堆的大小始终是24字节。

深堆(Retained Heap)的概念略微复杂。要理解深堆,首先需要了解保留集(Retained Set)。对象A的保留集指当对象A被垃圾回收后,可以被释放的所有的对象集合(包括对象A本身),即对象A的保留集可以被认为是只能通过对象A被直接或间接访问到的所有对象的集合。通俗地说,就是指仅被对象A所持有的对象的集合。深堆是指对象的保留集中所有的对象的浅堆大小之和。

注意:浅堆指对象本身占用的内存,不包括其内部引用对象的大小。一个对象的深堆指只能通过该对象访问到的(直接或间接)所有对象的浅堆之和,即对象被回收后,可以释放的真实空间。

另外一个常用的概念是对象的实际大小。这里,对象的实际大小定义为一个对象所能触及的所有对象的浅堆大小之和,也就是通常意义上我们说的对象大小。与深堆相比,似乎这个在日常开发中更为直观和被人接受,但实际上,这个概念和垃圾回收无关。

如图下图所示,显示了一个简单的对象引用关系图,对象A引用了C和D,对象B引用了C和E。那么对象A的浅堆大小只是A本身,不含C和D,而A的实际大小为A、C、D三者之和。而A的深堆大小为A与D之和,由于对象C还可以通过对象B访问到,因此不在对象A的深堆范围内。

 在MAT中查看对象浅堆和深堆的大小:

 选中对象,单击右键,在弹出的菜单中都有 Show Retained Set 命令,它可用于显示指定类或者对象的保留集。

内存分析报告

 可以生成内存分析报告,报告中检测出一个异常

 等等,MAT功能还是挺多的,可以多玩玩。


http://www.ppmy.cn/news/1047074.html

相关文章

为什么终端是1是从1到1的水仙花数呢

为什么终端是1是从1到1的水仙花数呢 #include<stdio.h> #include<math.h> int main() { int a,num_init,num; printf(“请输入水仙花数产生的下限值:”); num_init scanf(" %d", &num_init); printf(“请输入水仙花数产生的上限值:”); a scanf…

无重复字符的最长子串——力扣3

滑动窗口 int lengthOfLongestSubstring(string s){int n=s.size();unordered_set<char

基于YOLOv8模型和PCB电子线路板缺陷目标检测系统(PyTorch+Pyside6+YOLOv8模型)

摘要&#xff1a;基于YOLOv8模型PCB电子线路板缺陷目标检测系统可用于日常生活中检测与定位PCB线路板瑕疵&#xff0c;利用深度学习算法可实现图片、视频、摄像头等方式的目标检测&#xff0c;另外本系统还支持图片、视频等格式的结果可视化与结果导出。本系统采用YOLOv8目标检…

12_Redis为什么这么快高性能设计之epoll和IO多路复用深度解析

Redis为什么这么快&高性能设计之epoll和IO多路复用深度解析 一、before 多路复用要解决的问题 结论 二、IO多路复用模型 2.1 是什么 IO&#xff1a;网络IO多路&#xff1a;多个客户端连接&#xff08;连接就是套接字描述符&#xff0c;即socket或者channel&#xf…

Qt应用开发(基础篇)——纯文本编辑窗口 QPlainTextEdit

一、前言 QPlainTextEdit类继承于QAbstractScrollArea&#xff0c;QAbstractScrollArea继承于QFrame&#xff0c;是Qt用来显示和编辑纯文本的窗口。 滚屏区域基类https://blog.csdn.net/u014491932/article/details/132245486?spm1001.2014.3001.5501框架类QFramehttps://blo…

PostgreSQL could not identify an equality operator for type json

问题 我的SQL&#xff1a; select {"id":"1"}::json UNION select {"id":"2"}::json;在将两个含有json字段的表union时&#xff0c;报错了&#xff1a; > ERROR: could not identify an equality operator for type json分析 …

oj在线编程输入输出

练习地址&#xff1a;校招笔试真题_C工程师、golang工程师_牛客网 1.读取多行内容 输入描述&#xff1a; 输入包括两个正整数a,b(1 < a, b < 1000),输入数据包括多组。 输出描述&#xff1a; 输出ab的结果输入例子&#xff1a; 1 5 10 20 输出例子&#xff1a; 6 30imp…

MySQL安装、配置和启动关闭

1. 内容概述 本文主要内容&#xff1a; MySQL下载&#xff1b;MySQL的安装&#xff1b;配置环境变量&#xff1b;登录MySQL服务器&#xff1b;查询系统数据库&#xff1b;启动和关闭服务&#xff1b; 2. 安装、配置、启动与关闭服务 2.1. MySQL下载 在MySQL官网就可以下载…