记一次堆内存泄漏排查过程
- 前言
- 定位问题
前言
写了一个升级脚本,执行过程中给内存干爆了,不作处理,自己又好了,神奇吗?
- 日志中内存溢出:java.lang.OutOfMemoryError: Java heap space
定位问题
top命令查看最耗CPU的进程(进程:18382;CPU持续飙到595%+)
#输入top命令后键入P(大写P),进程按照CPU从高到底排序
top
-
查看该进程中最耗CPU的线程(发现有一些线程占用CPU较高)
#18382为进程号,键入P(大写P),该进程中的线程按照CPU从高到底排序
top -Hp 18382
-
将线程号转为16进制,同时查看这些线程当前正在干什么(在此以17045线程为例)
#将线程号转为16进制;其中17045为线程号
printf ‘%x\n’ 17045
#18382为进程号,0x4295为最耗CPU线程的十六进制
jstack 18382| grep ‘0x4295’ -C10 --color
-
可以看到最耗CPU的线程都是在进行GC
-
用Jmap命令查看当前堆的使用情况(发现老年代现在已占用99.8%+)
#其中18382为进程号
jmap -heap 18382
下图不是我分析的,是别人的,我做个笔记
- 查看gc频率的命令(其中O代表老年代占用率,FGC是FullGC次数,FGCT是fullGC时间;可以看出在频繁FullGC但是老年代有资源一直释放不掉)
#其中18382为进程号,5000是指每5秒(5000毫秒)输出一次
jstat -gcutil 18382 5000
这个对我来说意义也不是很大
到此,我可以得出是因为堆内存溢出导致。
- 分析问题产生原因
- 在触发堆内存溢出的时候:执行命令
生成dump文件命令
#其中fileName是导出后dump名称,pid为进程号
jmap -dump:format=b,file=fileName.dump pid
将dump文件导出到本地,用visualVM.exe(下载地址:https://visualvm.github.io/) 进行分析
- 查看对象
由此明白了,是因为sql查询返回的数据量太大导致的。
若有错误,希望大佬指出。
对你有帮助给点个👍再走呗。