一次JAVA内存泄漏的定位分析过程

正式环境老是内存用完崩溃。

在本地模拟以及解决过程

查询JAVA线程,命令:jps -lvm

生成dump文件:jmap -dump:live,format=b,file=aaa.hprof 22400

使用工具MAT分析:

一次JAVA内存泄漏的定位分析过程_第1张图片

在Leak Suspects页面会给出可能的内存泄露,进入Leak Suspects,查看那些类可能发生内存泄露

一次JAVA内存泄漏的定位分析过程_第2张图片

发现自己写的类:

一次JAVA内存泄漏的定位分析过程_第3张图片

线程池的问题,进入Details查看详情:

在详情页面Shortest Paths To the Accumulation Point表示GC root到内存消耗聚集点的最短路径,如果某个内存消耗聚集点有路径到达GC root,则该内存消耗聚集点不会被当做垃圾被回收。

一次JAVA内存泄漏的定位分析过程_第4张图片

在All Accumulated Objects by Class列举了该对象所存储的所有内容。

一次JAVA内存泄漏的定位分析过程_第5张图片

发现问题所在:java.util.concurrent.ThreadPoolExecutor对象占用内存太大。

而引用这个对象的是DoctorAdviceSplitJob类,那么直接看该类代码:

一次JAVA内存泄漏的定位分析过程_第6张图片

由于该类不是单例的(quatz的坑),每执行一次任务就会新创建一个线程池,每个线程池中创建多个线程,所以跑几次任务后,内存便被消耗完。

解决办法:将创建线程池的代码迁移到单例类中,在job类中引用该线程池。

欢迎关注公众号:

你可能感兴趣的:(Java核心技术分析)