Java OOM定位处理

本文针对处理 OOM 的定位问题,查询以及解决问题。

1. 常见的几种方式

1.1. GC overhead limit exceeded

Java.lang.OutOfMemeoryError:GC overhead limit exceeded

即程序在垃圾回收上花费了98%的时间,却收集不回2%的空间,通常这样的异常伴随着CPU的冲高。不同的垃圾回收器 OOM 的异常错误不同。

1.2. StackOverflowError (栈溢出)

java.lang.StackOverflowError

1.3. PermGen space (元空间耗尽)

Java.lang.OutOfMemoryError: PermGen space

1.4. Java heap space (堆内存溢出)

java.lang.OutOfMemoryError: Java heap space

1.5. Direct buffer memory (用来 nio ,但是 direct buffer 不够)

java.lang.OutOfMemoryError: Direct buffer memory

2. OOM 定位

2.1. GC overhead limit exceeded

/**
 * jvm参数配置
 * -Xms40m  最小堆
 * -Xmx40m  最大堆
 * -XX:+HeapDumpOnOutOfMemoryError 堆异常输出dump文件
 * -XX:HeapDumpPath=D:\360MoveData\Desktop 输出dump文件路径
 */
@SpringBootApplication
public class XulinglinApplication {

    public static void main(String[] args) {
        SpringApplication.run(XulinglinApplication.class, args);
    }

    //初始化60w数据到HashMap中
    @Bean
    public HashMap hashMapdump(){
        HashMap hashMap = new HashMap();
        for (int i = 0; i <600000 ; i++) {
            hashMap.put(i,i);
        }
        return hashMap;
    }
}

2.2. 异常错误log日志

Caused by: java.lang.OutOfMemoryError: GC overhead limit exceeded
    at java.util.HashMap.newNode(HashMap.java:1734) ~[na:1.8.0_91]
    at java.util.HashMap.putVal(HashMap.java:630) ~[na:1.8.0_91]
    at java.util.HashMap.put(HashMap.java:611) ~[na:1.8.0_91]
    at com.xulinglin.XulinglinApplication.hashMapdump(XulinglinApplication.java:20) [classes/:na]
    at com.xulinglin.XulinglinApplication$$EnhancerBySpringCGLIB$$a8f9ee58.CGLIB$hashMapdump$0() ~[classes/:na]
    at com.xulinglin.XulinglinApplication$$EnhancerBySpringCGLIB$$a8f9ee58$$FastClassBySpringCGLIB$$9b30d517.invoke() ~[classes/:na]

文件名称:java_pid73956.hprof,hprof 可以格式让我们更好的利用第三方插件来定位问题。比如使用 Eclipse IDE

2.3. Hprof 拖入 Eclipse IDE分析


通过上图,可以基本确定导致内存溢出的代码位置。


通过 IDE 分析dump文件,查看栈的信息,查看导致内存溢出的对象或容器里具体存储什么信息来定位具体原因