首页 > 系统相关 >MAT分析堆内存占用

MAT分析堆内存占用

时间:2023-02-18 16:13:23浏览次数:48  
标签:MAT dump 占用 list 内存 jvm

MAT介绍

MAT是Memory Analyzer tool的缩写,是一种快速,功能丰富的Java堆分析工具,能帮助你查找内存泄漏和减少内存消耗。很多情况下,我们需要处理测试提供的hprof文件,分析内存相关问题,那么MAT也绝对是不二之选。

下载地址:Eclipse Memory Analyzer Open Source Project | The Eclipse Foundation

image-20230218145730140

演示OOM

因为MAT是对java堆内存快照进行分析的工具,拿到内存快照文件的方法如下:

  • jmap -dump:live,format=b,file=dump.hprof PID 使用jmap命令拿到给定PID的jvm进程的堆内存,生产、本地环境均可使用。
  • -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=dumpPath 生产可使用的方法,添加这两个jvm参数,一旦jvm发生OOM的时候,会自动生成jvm堆内存dump文件。非常建议生产加上这两个jvm参数。
  • jvisualvm工具,该工具是jdk自带的工具,也可以拿到dump文件,一般本地测试使用。

下面我演示第二种方法:

先设置jvm参数:为方便演示oom的出现,我设置堆内存大小最大为50M,oom发生时会把自动生成的dump文件存放在C:\Users\MSI-\Desktop\1路径下。

-Xmx50M -Xms50M -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=C:\Users\MSI-\Desktop\1

代码:

这里有一个启动类,启动类启动时,会在list中存入50000个UUID,因为list是static修饰的,所以该list有GC ROOTS,即便发生full gc,也不会回收该对象。

还有一个DumpController,当请求接口时,会往成员变量list中塞入50000个UUID,因为DumpController长期存在,list也有GC ROOTS,gc时也不会回收该对象。

@SpringBootApplication
@ConfigurationPropertiesScan
public class MinioApplication {

    static List<String> list = new ArrayList<>();

    public static void main(String[] args) {
        for (int i = 0; i < 50000; i++) {
            list.add(UUID.randomUUID().toString());
        }
        SpringApplication.run(MinioApplication.class, args);
    }

}

@RestController
@RequestMapping("/dump")
public class DumpController {
    ArrayList<String> list = new ArrayList<>();

    @GetMapping("/test")
    public String test() {
        for (int i = 0; i < 50000; i++) {
            list.add(UUID.randomUUID().toString());
        }
        return "ok";
    }
}

下面,进行测试:

调用:http://localhost:8080/dump/test

调用几次后,发现直接卡死。控制台输出错误:

image-20230218152521072

抛出一个Error:java.lang.OutOfMemoryError:GC overhead limit exceeded GC

回收时间过长时会抛出该异常,过长的定义是,超过98%的时间用来做GC并且回收了不到2%的堆内存。

先用jvisualvm工具分析堆内存占用情况:

image-20230218151444517

这里发现整个老年代和伊甸园区都被占满,并且上面分析过main方法中的list和DumpController中的list都无法被gc回收,导致了OOM,这时候已经无法创建新的对象存放到堆中。

MAT分析内存占用

上面配置过dump文件的生成路径,去该路径下看,确实生成了一个hprof,全名是heap profile,译为堆快照文件。

image-20230218152542634

使用MAT打开该文件,选择Open a Heap Dump

image-20230218151944920

选择Leak Suspects Report,这样MAT就会向用户报告可能发生内存泄漏的地方:

image-20230218152110805

点击首页,会有一个饼状图,直接就显示了有两个可能发生内存泄漏的地方:一个占用29.6M,一个占用5.6M

image-20230218152717298

下面有详细信息:明确指出两个地方,一个是主启动类,一个是DumpController。与我们分析一致。

image-20230218152802381

分析内存快照,说白了,无非就是找到占用内存最大的对象,然后就是找到谁在引用这个对象,是哪个线程在引用,接着找到创建这些对象的相关代码和方法,然后你就可以一头扎到对应的源码里去分析问题了。

点击dominator_tree,这里就会按内存占用大小的降序排列出jvm中的对象。这里可以看到前两个就是DumpController和主启动类,一个30M,一个5M多。

image-20230218153135792

包括对象中各个成员变量:

image-20230218153453287

找到占用内存最大的对象之后,最后一步就是要定位一下是哪一行代码,或者是哪个方法创建了那么多的对象?

这个又需要另外一个视图了,点击下图的红圈处,会进入thread_overview界面,这里会展示出来JVM中所有的线程以及每个线程当时的方法调用栈帧,以及每个方法中创建了哪些对象:

image-20230218153654764

image-20230218153905762

标签:MAT,dump,占用,list,内存,jvm
From: https://www.cnblogs.com/wwjj4811/p/17132854.html

相关文章

  • Ubuntu环境下安装MATLAB
    在Linux下安装MATLAB,当以root权限安装时,可能会出现运行安装文件但无响应的情况,则按以下步骤安装即可解决此问题:键入命令xhost+SI:localuser:root进入安装文件夹......
  • org.springframework.beans.factory.NoUniqueBeanDefinitionException:expected singl
    这是因为从bean容器中找到的bean不是唯一的,找到了2个匹配的bean,这时候注入bean就会报错。比如说一个service接口有两个实现类  一、@Autowired方式注入    ......
  • volatile的实现原理-内存屏障
     被volatile修饰的变量在编译成字节码文件时会多个lock指令,该指令在执行过程中会生成相应的内存屏障,以此来解决可见性跟重排序的问题。内存屏障的作用:1.在有内存屏障......
  • 使用Animate.css制作超炫的CSS3动画
    Animate.css是一个超强的CSS3动画库,它使用简单,只需要将相关效果对应的class加入页面元素中,就能实现翻转、滑动、旋转等等复杂超炫的跨浏览器的动画效果,它让开发这制作页面动......
  • 指针,动态内存的例子
    #include<stdio.h>int*pPointer;voidSomeFunction();{intnNumber;nNumber=25;//makepPointerpointtonNumber:pPointer=&nNumb......
  • C语言之内存讲解
    目录1内存讲解1.1作用域1.1.1局部变量1.1.2静态static局部变量1.1.3全局变量1.2内存布局1.2.1内存分区1.2.2代码区(textsegment)1.2.3全局初始化数据区/静态数据区......
  • PHP超低内存遍历目录文件和读取超大文件
    前言这篇笔记主要解决这么几个问题:PHP如何使用超低内存快速遍历数以万计的目录文件?PHP如何使用超低内存快速读取几百MB甚至是GB级文件?顺便解决哪天我忘了可以通过搜索引擎......
  • java中的数据类型及内存分析
    1. java中的类型           (1)除基本类型之外的变量类型都称之为引用类型。   (2)java中的变量        ①局部变量:使用前必须被......
  • 基于扩展卡尔曼滤波的自适应智能无人车辆行驶matlab仿真,输出三维动态行驶动画
    1.算法描述        EKF扩展卡尔曼滤波要解决的是卡尔曼滤波不适用于非线性模型的问题。其和卡尔曼滤波算法结构相同,只是将非线性模型线性化,然后再应用卡尔曼滤波......
  • 基于蚁群算法的二维路径规划matlab仿真
    1.算法描述蚁群算法是一种用来寻找优化路径的概率型算法。它由MarcoDorigo于1992年在他的博士论文中提出,其灵感来源于蚂蚁在寻找食物过程中发现路径的行为。这种算法具有......