Skip to content

内存问题排查总结

堆内存dump

1 jmap ‐dump:format=b,file=eureka.hprof 14660

可以配置自动 dump 文件,在内存溢出的时候会自动 dump 文件。

-XX:+HeapDumpOnOutOfMemoryError

比如应用的启动脚本,开启自动 dump 文件。

exec java -classpath $CLASSPATH -Xms1024m -Xmx2048m
-XX:+HeapDumpOnOutOfMemoryError
-Dquery.type=es
-Dfile.encoding=UTF-8 org.vlis.cloudmonitor.server.ApiServerApplication $*

使用MAT排查内存泄漏

测试代码

java
    private static ExecutorService executorService = Executors.newFixedThreadPool(500);

    @GetMapping("/object")
    public void testObject() {
        for (int i = 0; i < 100; i++) {
            executorService.submit(() -> {
                //对象列表更明显
                List<UserVo> userVoList = userService.getUserVoList();
                System.out.println(userVoList.size());
            });
        }
    }
java
public class UserService {

    //不手动remove
    private static ThreadLocal<List<UserVo>> threadLocal = new ThreadLocal<>();

    public List<UserVo> getUserVoList() {
        if (threadLocal.get() == null) {
            List<UserVo> list = new ArrayList<>();
            for (int i = 0; i < 1000; i++) {
                list.add(UserVo.getTestData());
            }
            threadLocal.set(list);
        }
        return threadLocal.get();
    }

}

测试结论

  • no-gc

    查看对象个数,50w个

    结合MAT给出的内存泄漏推测,有50w个对象。

  • gc

    使用 jconsole手动gc之后,MAT分析的还是有50w个对象。

    GC无法有效回收线程里,存放到ThreadLocal里面的对象,造成了内存泄漏。

使用MAT排查内存溢出

查看大对象

image.png

查看内存泄漏

image.png