文章目录
- 1、前言
- 2、MAT独立程序的下载安装
- 3、得到一个内存溢出的dump
- 3.1、主动方式
- 3.2、被动方式
- 4、MAT工具对dump文件的分析
1、前言
生产环境中,我们可能会遇到Java内存溢出Out Of Memory。此时我们可以借助内存分析工具MAT(Memory Analyzer Tool),来定位是哪里出现了问题。
2、MAT独立程序的下载安装
MAT(Memory Analyzer Tool)下载地址:http://www.eclipse.org/mat/downloads.php
根据自己的安装环境,选择操作系统和JDK对应的MAT版本,我这里选择的是Windows (x86_64)。下载好的压缩包解压到本地任意一个文件夹里,然后就可以开始使用了(MAT运行环境需要依赖JDK)。下图是我的解压路径,圈注的就是启动MAT程序执行文件。
解压后目录内有个MemoryAnalyzer.ini文件,该文件里面有个-Xmx参数。该参数表示最大内存占用量,默认为1024m。
建议修改为小于本机内存大小,大于要分析的dump文件大小
-startup
plugins/org.eclipse.equinox.launcher_1.5.0.v20180512-1130.jar
--launcher.library
plugins/org.eclipse.equinox.launcher.win32.win32.x86_64_1.1.700.v20180518-1200
-vmargs
### -Xmx1024my原本默认为1024m,此处我修改为4096m
-Xmx4096m
3、得到一个内存溢出的dump
如何生成dump文件,有主动和被动两种方式。我们先启动一个准备好的Springboot程序
package com.wzl.xman.servicea.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.List;
@RestController
public class MemoryController {
private static List list = new ArrayList<Byte[]>();
@GetMapping(value = "/oom/{size}")
public String outOfMemoryTest(@PathVariable(value = "size") Long size) {
//根据传入size的大小,可能会引起OOM内存溢出
for (int i = 0; i < size; i++) {
Byte[] bytes = new Byte[1024];
list.add(bytes);
}
return "ok";
}
}
nohup java -jar -server -Xms256m -Xmx256m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/opt/oom/heapdump.hprof xman-service-a-0.0.1-SNAPSHOT.jar &
3.1、主动方式
主动生成dump文件,首先查找运行的Java程序的PID,可用top或者ps命令查找。
###top命令找资源消耗最高的
top
###ps命令精确查找java进程
ps -ef|grep java
然后使用jmap命令生成dump文件,file后面是dump文件的保存路径名称,2033则是java程序的PID
jmap -dump:format=b,file=/opt/oom/heapdump.hprof 2033
注意:主动获取dump文件必须是一出现内存异常就获取dump文件,这样获取的文件信息才比较准确。如果无法及时获取,推荐通过第二种方式获取dump文件。
3.2、被动方式
- 被动方式就是在程序启动的时候增加了参数:
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/opt/oom/heapdump.hprof- 在JVM出现内存溢出的情况下,JVM会自动生成dump文件
nohup java -jar -server -Xms256m -Xmx256m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/opt/oom/heapdump.hprof xman-service-a-0.0.1-SNAPSHOT.jar &
敲击一个会导致内存溢出的请求:http://192.168.12.11:31002/oom/1000000
此时应用宕机,生成.hprof文件
4、MAT工具对dump文件的分析
我们分析通过被动方式生成测dump文件
- 启动MAT工具,选择File – Open Heap Dump…,导入dump文件
红色部分是我们要重点看的,接下来我们看Details:
- 可以看到MemoryController类中存在一个ArrayList集合,存放了大量的new Byte[1024]数据。光这一个对象就占用总大小的94.6%,这就是问题的根源,然后就可以分析代码存在的问题了。
- 更多MAT的使用方式,请自行百度