一次JAVA内存泄漏的定位分析过程
正式环境老是内存用完崩溃。
在本地模拟以及解决过程
查询JAVA线程,命令:jps -lvm
" class="reference-link">
生成dump文件:jmap -dump:live,format=b,file=aaa.hprof 22400
" class="reference-link">
使用工具MAT分析:
" class="reference-link">
在Leak Suspects页面会给出可能的内存泄露,进入Leak Suspects,查看那些类可能发生内存泄露
" class="reference-link">
发现自己写的类:
" class="reference-link">
线程池的问题,进入Details查看详情:
在详情页面Shortest Paths To the Accumulation Point表示GC root到内存消耗聚集点的最短路径,如果某个内存消耗聚集点有路径到达GC root,则该内存消耗聚集点不会被当做垃圾被回收。
" class="reference-link">
在All Accumulated Objects by Class列举了该对象所存储的所有内容。
" class="reference-link">
发现问题所在:java.util.concurrent.ThreadPoolExecutor对象占用内存太大。
而引用这个对象的是DoctorAdviceSplitJob类,那么直接看该类代码:
" class="reference-link">
由于该类不是单例的(quatz的坑),每执行一次任务就会新创建一个线程池,每个线程池中创建多个线程,所以跑几次任务后,内存便被消耗完。
解决办法:将创建线程池的代码迁移到单例类中,在job类中引用该线程池。
欢迎关注公众号:
" class="reference-link">
还没有评论,来说两句吧...