Java OOM异常定位思路
1.概述
- OOM:OutOfMemory(内存溢出),一般是内存不足导致。JVM规范规定了,除了程序计数器外,其他的运行时内存区域都有可能发生OOM。
2.发生OOM的内存区域有哪些?
- Java堆
- 虚拟机栈、本地方法栈
- 方法区、运行时常量池
- 直接内存
3.OOM可能的区域以及原因
Java堆
-
原因
堆是用来存放实例对象的,如果不断地去创建对象并且GC Roots到对象之间是可达的, 垃圾收集器就回收不了这些对象,随着此类对象数量的增加, 占用内存超过最大堆的内存限制后就会产生内存溢出异常。
-
测试
- 前提条件
在idea中的Edit Configuration的VM Options中添加如下参数 -verbose:gc -Xms20m -Xmn10m -Xmx20m -XX:+PrintGCDetails -XX:SurvivorRatio=8 -verbose:gc:控制台输出GC日志 -Xms:初始内存大小(memory size) -Xmn:最小内存 -Xmx:最大内存 -XX:+PrintGCDetails:控制台输出GC具体日志信息 -XX:SurvivorRatio=8:Eden区占比。新生代分为Eden区和Survivor区(from/to Survivor),SurvivorRatio参数定义了Eden、Survivor的比例,默认为8,也就是Eden占新生代的8/10
- 测试代码
public class HeapOOM { public static void main(String[] args) { List<HeapOOM> list = new ArrayList<>(); while (true) { list.add(new HeapOOM()); }