Bootstrap

【Jvm内存】EclipseMemoryAnalyzer分析内存


前言

MemoryAnalyzer使用分析内存GC问题,安装下载地址如下http://www.eclipse.org/mat/downloads.php,选择系统对应版本,否则报错
JDK自带分析工具 性能监控工具 jvisualvm.exe,VisualVM 是 JDK1.6 开始自带的一款全能型性能监控和故障分析工具。包括对 CPU 使用、JVM 堆内存消耗、线程、类加载的实时监控,内存 dump 文件分析,垃圾回收运行情况的可视化分析等,对故障排查和性能调优很有帮助

为什么要有GC? 首先JAVA和ASP.NET都有GC 垃圾回收一个跟踪过程,它传递性地跟踪指向当前使用的对象的所有指针,以便找到可以引用的所有对象,然后重新使用在此跟踪过程中未找到的任何堆内存。公共语言运行库垃圾回收器还压缩使用中的内存,以缩小堆所需要的工作空间,因为你没有足够多的内存,并且,你挺懒,不去自己清理内存,所以就有了 GC 什么是GC GC的全称是garbage collection,中文名称垃圾回收,是.net中对内存管理的一种功能。垃圾回收器跟踪并回收托管内存中分配的对象,定期执行垃圾回收以回收分配给没有有效引用的对象的内存。当使用可用内存不能满足内存请求时,GC会自动进行。 在进行垃圾回收时,垃圾回收器回首先搜索内存中的托管对象,然后从托管代码中搜索被引用的对象并标记为有效,接着释放没有被标记为有效的对象并收回内存,最后整理内存将有效对象挪动到一起,这就是GC的四个步骤。 由上可见,GC是很影响性能的,所以一般说来这种事情况还是尽量少发生为好。 为了减少一些性能影响,.net的GC支持对象老化,或者说分代的概念,代是对象在内存中相对存现时期的度量单位,对象的代数或存现时期说明对象所属的代。目前.net的垃圾回收器支持三代。每进行一次GC,没有被回收的对象就自动提升一代。较近创建的对象属于较新的代,比在应用程序生命周期中较早创建的对象的代数低,最近代中的对象位于零代中。


使用步骤

1.导入文件

导入需要分析dump文件
导入需要分析dump文件,文件格式为 20220308.hprof

2.读取数据

在这里插入图片描述

3.分析数据

在这里插入图片描述
根据上述问题所在比例进行分析,占比越大说明使用内存越多,需要重点排查
在这里插入图片描述
根据日志信息找点自己的业务代码,重点排查业务逻辑
在这里插入图片描述
找到占用内存多的实体类对象进行分析
在这里插入图片描述
找到占用内存多的数据库查询语句进行分析


总结

  1. 该问题发生的现象:系统中使用了多个while(true)无线循环线程去发送数据,线程运行一段时间后所有线程自动断开,且收到内存告警短信。
  2. 问题的初步排查:仔细核对业务逻辑,发现业务逻辑中在无线循环线程中有业务会导致报错,初步判断是报错导致线程中断,但是修改业务逻辑后并没有解决该问题。
  3. 问题的二次排查:无线循环线程中使用了大量内存队列,机器内存有限,当业务系统数量越来越多的消耗系统资源,出现了抢夺资源问题,其中可能有一个无线循环线程中队列争抢不过,导致线程出现异常,导致中断,中断后的无线循环线程无法消费内存队列里的数据,但是内存队列的生产行为还在继续,因此随着时间的积累,内存队列越来越大,导致内存资源越来越小,导致连锁反应,其他无线循环线程全部停止。
  4. 问题的进一步分析:经仔细排查业务处理逻辑,发现在无线循环中,每隔几秒,就会new很多新的对象,也会占用大量内存。
  5. 最后解决方案:while(true)无线循环线程发送业务数据逻辑,修改为定时任务,这样就保证了不会出现内存队列中数据随着时间一直递增状态,同时也不会频繁new新的对象,导致内存队列越来越大,从而引发由于内存不足而引起的一系列连锁问题。
;