在java进程发生内存溢出时导出堆内存快照有如下几种方式:

1.jvm环境变量设置内存溢出自动导出

jvm参数:-Xmx32M -Xms32M -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./

社区版本idea执行可能无法导出内存映射,不使用idea即可。

java dump文件下载下来 java dump文件太大_java

 

提示:真实生产环境中,此种方式可能因为内存快照太大无法导出

2.jmap命令导出

2.1 使用jmap 帮助命令,查看一下帮助:

java dump文件下载下来 java dump文件太大_ide_02

2.2 使用命令导出:

java dump文件下载下来 java dump文件太大_ide_03

3.额外说明

jmap可以查看堆内存的一些详细信息:如下所示

java dump文件下载下来 java dump文件太大_java_04

4.单独MAT分析内存dump文件

4,1 首先安装:

安装地址:Eclipse Memory Analyzer Open Source Project | The Eclipse Foundation

java dump文件下载下来 java dump文件太大_ide_05

根据自己情况,是否捐赠。如果不想捐赠,在下载页面选择阿里的镜像,即可(最新版本不支持jdk8): 

java dump文件下载下来 java dump文件太大_ide_06

支持jdk8的版本:

java dump文件下载下来 java dump文件太大_内存溢出_07

 

4.2 启动MAT:

点击如下exe文件:

java dump文件下载下来 java dump文件太大_ide_08

java dump文件下载下来 java dump文件太大_内存溢出_09

需要注意的是,如果dump文件太大,需要调整它的内存才可以完成大dump文件的加载,这个配置文件需要exe启动后会自动生成:

java dump文件下载下来 java dump文件太大_内存溢出_10

4.3 MAT分析dump文件

这里给个程序实例:无限循环添加user。

java dump文件下载下来 java dump文件太大_内存溢出_11

查看概览,看到对象所占比例及排序:显然有个对象不正常,占了19m(我设置最大堆32m)

java dump文件下载下来 java dump文件太大_ide_12

点击查看MAT详细分析结果:MAT猜想导致堆栈溢出原因

 

java dump文件下载下来 java dump文件太大_ide_13

 

 根据上图可以看到两个猜想的原因:

1.一个对象concurrenthashmap占据了65%的堆空间;

2.class文件加载过多,占据了14%。

毫无疑问是前者这个对象占据太多的原因,怎么分析尼?

点击如下图的柱状图(红色矩形框)查看对象实例数量排序,在正则表达式可以输入自己的包名过滤一下:

java dump文件下载下来 java dump文件太大_java_14

这里类对象16w个,显然不正常,我们可以查下谁引用的:

java dump文件下载下来 java dump文件太大_内存溢出_15

 

java dump文件下载下来 java dump文件太大_内存溢出_16

 

以下截图矩形的指定的按钮是查看类对象数量的:

java dump文件下载下来 java dump文件太大_java dump文件下载下来_17

可以看到占据最多空间的对象为第一个,点看如下:

java dump文件下载下来 java dump文件太大_java dump文件下载下来_18

 

结合概览、猜想及这两个查看类数量、类空间占据大小基本可以定位问题。