1. 前言
工作中有可能遇到 java.lang.OutOfMemoryError: Java heap space 内存溢出异常, 本文提供一些内存溢出的分析及解决问题的思路.
常见异常如下:
2022-01-31 16:07:29.639 ERROR 1981 --- [http-nio-8080-exec-4] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Handler dispatch failed; nested exception is java.lang.OutOfMemoryError: Java heap space] with root cause
java.lang.OutOfMemoryError: Java heap space
2. 内存溢出的问题
解决问题之前先来分析一下为什么会出现内存溢出的问题.
有两种可能性:
一种是应用有问题, 本该回收的内存没有进行回收导致的内存溢出, 这种情况就需要修改代码了.
第二种情况则是服务器资源不够或JVM参数设置过小导致的内存溢出,这种情况需要更换服务器或修改启动参数
我们可以使用对应的工具或命令来定位到问题, 然后分析是哪种情况, 最后再解决问题.
3. 场景模拟
通过下列代码来模拟内存溢出的情况:
// 通过无限创建自定义对象模拟内存溢出的场景
@GetMapping("oom")
public void oom(){
while(true){
CustomObj customObj = new CustomObj();
}
}
/**
* @author liuboren
* @Title: 自定义对象
* @Description: 创建该对象用于模拟OOM场景
* @date 2022/1/30 16:55
*/
public class CustomObj {
// 利用numbers成员变量尽可能更快的用光内存
private int[] numbers = new int[10000000];
}
再将应用的启动JVM参数设置为 -Xms70m -Xmx70m即可.
通过访问/oom的接口, 很快程序就会报
2022-01-31 16:07:29.639 ERROR 1981 --- [http-nio-8080-exec-4] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Handler dispatch failed; nested exception is java.lang.OutOfMemoryError: Java heap space] with root cause
java.lang.OutOfMemoryError: Ja