实验环境:cenos7
实验代码
不停的new对象加入list中
//list放到类成员变量
// 如果放到方法里面,方法结束后会,当内存不够,会触发gc,且list可被回收,不会造成内存泄露问题。
List<User> userlist = new ArrayList<>();
public void getUserList() {
while(true){
userlist.add(new User());
}
}
实验步骤
在controller中调用实验代码
/**
* 堆内存溢出
* @return
*/
@RequestMapping("/getUserList")
@ResponseBody
public String getUserList() {
deadLockService.getUserList();
return "getUserList";
}
部署项目到linux环境并启动简单演示
java -Xmx32M -Xms32M -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./ -jar order-0.0.1-SNAPSHOT.jar &
排查演示
调用接口:发现内存飙高,且日志打印出了内存溢出错误
可以看到,发生内存溢出时候,生成的文件
当然,也可以使用命令来导出内存溢出的快照文件,命令如下
先查对应的pid,5295为对应的pid
jps -l
jmap -dump:format=b,file=5295.hprof 5295
将文件导出来,文件一般比较大
sz 5295.hprof
借助内存分析工具MAT排查内存溢出问题。
MAT下载地址
https://eclipse.org/mat/downloads.php
发现了一个非常大的对象
继续打开报告看一下,发现了我们事先模拟的内存溢出对象位置,导致排查完毕。
也可以打开dominator_tree查看