堆溢出处理
程序员文章站
2022-07-15 15:46:37
...
在Java程序运行过程中,对象会不断的被新建和回收,而对象大部分情况下是放在堆空间中的,所以一旦对象太多导致堆空间不足,就会抛出OOM异常,也就是堆内存溢出了。
就像查案一样,程序出现问题的时候,先要保持现场信息,这样才方便排查问题,而JVM也为开发这提供了这样的手段,
使用参数-XX:+HeapDumpOnOutOfMemoryError
,让内存溢出的时候可以导出整个堆的信息,然后再加上-XX:HeapDumpPath
参数,把整个堆的信息导出到开发指定的文件路径,方便查找。两个参数配合就做到了当出现OOM时,可以尽可能的保存下现场信息。
接下来指定程序使用的虚拟机的工作模式为Server,然后指定最大堆大小为10M同时打印GC日志,最后再加上上述的两个参数,整体如下:
测试代码:
import com.google.common.collect.Lists;
import java.util.List;
/**
* 堆溢出导出文件
*/
public class DumpOOM {
public static class User {
private byte[] p;
}
public static User createUser() {
User user = new User();
//大约1M大小
user.p = new byte[1 * 1024 * 1024];
return user;
}
public static void main(String[] args) {
List list = Lists.newArrayList();
for (int i = 0; i < 10; i++) {
list.add(createUser());
System.out.println("list中的数量:" + list.size());
}
}
}
以上代码实现的逻辑就是,循环创建User对象实例,并加入到集合list中,因为设置的最大堆大小为10M,而User实例中单单一个p属性就大约为1M了,所以最后的结果肯定会发生OOM。
运行结果如下:
从输出结果可以发现,User实例有7个,同时也把堆信息文件导出到指定路径了。
使用Java VisualVM工具分析下堆信息文件,展示如下:
发现byte[]类型占据的空间最多,点击去看下实例视图,如下:
从大到小排列下,会发现前7个实例大致都是1M左右,然后这7个实例都和DumoOOM类下的User类的p属性相关。
回顾下之前程序的输出,list中的数量也只有7个,后面就抛出OOM了,数量和实例视图是对的上的。
总结
堆溢出时可以先导出堆信息文件保存,然后再配合上Java VisualVM工具找出导致堆溢出的对象。
推荐阅读
-
16核Zen 2处理器性能曝光:吊打9980XE 依然采用AM4接口
-
Intel:10nm的Ice Lake处理器相比前代有18% IPC提升
-
Flutter使用JsBridge方式处理Webview与H5通信的方法
-
ATX 2.52如何撑起你的12核处理器 该不该换呢?
-
Intel退役Kaby Lake-G处理器 A/I合体的杰作消失了
-
由于扩展配置问题而无法提供您请求的页面。如果该页面是脚本,请添加处理程序。如果应下载文件,请添加 MIME 映射。
-
springmvc处理模型数据ModelAndView过程详解
-
IE在spa应用下内存泄露的处理教程
-
springmvc处理模型数据Map过程解析
-
PythonTask03:异常处理