内存溢出问题,MAT使用

内存溢出问题,MAT使用

问题

mat一般是用来对内存进行分析的,可以通过jamp生成,或者说在服务启动时,配置HeapDumpOnOutOfMemoryError这个jvm指令,然后生成即可

分析第一个问题
设置
  • windows->preferences->Memory Analyzer 里面可以设置展示的单位值,默认是Bytes
  • windows->preferences->Memory Analyzer 设置下 Keep unreachable Objects
    内存溢出问题,MAT使用_第1张图片
加载文件

打开MAT->点击【File】->【Open Heap Dump…】->选择堆转储文件并点击【打开】,如果需要加载的堆转储文件过大,记得调整MemoryAnalyzer.ini中的-Xmx

查看
  • 打开后,会默认打开Leak Suspects Report 默认选项或者在页面最下面点击 Leak Suspects,这个是会默认给你做分析的

内存溢出问题,MAT使用_第2张图片
内存溢出问题,MAT使用_第3张图片

定位
  • 从上面一排ConcurrentContext-pool这种线程名,就应该得查出来对应的代码了,但是具体还得分析

  • 打开dominator_tree

  • 保留堆大小(Retained Heap)排序(Retained Heap=对象本身大小与其所引用对象大小之和,理论上是假设该对象被GC成功,能释放多少内存;Shallow Heap=对象自身大小,正常情况下参考意义不大),看占用空间最大的几个对象

内存溢出问题,MAT使用_第4张图片

  • 展开Thread,可以看下相关数据,比如一些String的数据,上数据库区查询,发现是大的PDF文件,内存溢出问题,MAT使用_第5张图片
  • 查询对应的线程名,发现也是在生成大PDF的定时任务每次生成的大PDF,有几百兆,并且线程池设置的队列是0,最大线程数是Integer.Max_value,所以如果量比较大,这些PDF文件在生成时,都是在内存里面byte数组的,占用内存比较多,把内存占满
  • 看对应的线程堆栈

内存溢出问题,MAT使用_第6张图片

  • 展开后可以看到对应的代码内存溢出问题,MAT使用_第7张图片
  • 后面也主要是根据代码进行分析,看内存是被谁占用的
  • 最终发现,是批量生成大的PDF文件时,PDF文件过大,而且线程池又是设置的Integer.max_value,导致内存被占满,然后溢出
分析第二个问题
分析

主要分析过程和上面差不多,目前这个问题是因为在根据图片生成一些文件时出现内存溢出,最终排查过程发现,图片是13M左右,像素很大是7600*10134 ,对图片加载会有对应的代码生成一些byte数组和int数组,如果图片是13M左右,读到内存里面差不多会有200M吧,代码当然有些也可以优化,业务方面又是有上传,有生成,最终导致一个13M左右的文件,在内存里面差不多达到了800M,然后又7,8个这样的文件同时处理,导致内存溢出了

图片
  • 主要看了线程占用的内存大小,哪边占用,然后通过thread栈找到对应代码,去分析。这里面也可以看到一些图片的名字,找到这些图片发现都吃13M的文件,在结合网上一些大图片的处理问题,可以推出来。最终替换了文件也解决掉了

内存溢出问题,MAT使用_第8张图片

内存溢出问题,MAT使用_第9张图片

你可能感兴趣的:(线上问题处理思路)