Java - 排查处理过jvm内存泄漏的问题吗?MAT了解一下
前面说到我们在做压力测试的时候,竟然把整个k8s集群的服务搞挂了,其实问题有两个,第一是因为没有给服务所在的pod设置最大的资源限制,第二是因为服务本是有内存泄漏的问题的;
开始我以为的是将pod的资源限制配置好,就行了,测试了一把后,发现每10个小时,服务的memory就已经到达设置的最大限制2G内存,而自动重启restart了,虽然从业务上来讲,只会影响这个pod的服务而不再影响整个集群的运行,但是依旧有不小的问题,那就是服务竟然不断的占用内存,而不会释放,这明显是内存泄漏啊!
第一时间,想到的就是去排查代码,but,从哪里入手呢,总得有个线索查下去吧,对了,进到服务所在的pod,top一把呗!
第一步:一般我们只在一个pod里面放一个容器,而这个容器的服务通常以PID为1,来运行,所以我们直接:
$ top -p 1 #查看服务所在进程的CPU和MEM信息
第二步:通过命令 jmap –heap 进程id (目的是确定内存分配是否正确,以及jvm中内存的实时状态)
$ jmap -heap 1 #查看内存目前的使用情况以及垃圾回收情况
, 但是我执行后没有我想要的信息,略过咯
第三步:jmap -histo:live PID | more #打印堆的对象统计,包括对象数、内存大小等等。
jmap -histo:live 这个命令执行,JVM会先触发gc,然后再统计信息
$ jmap -histo:live PID | more
#会看到正在运行的服务各个对象的个数,让我们有一个查问题起码的方向
第四步:jmap -dump:format=b,file=heap.bin PID #dump堆到文件,format指定输出格式,live指明是活着的对象,file指定文件名
$ jmap -dump:format=b,file=heap.bin 1 #可抓取正在运行的堆栈详细信息,并输出文件到当前目录
第五步:拿到这个堆栈信息的文件(heap.bin)后,可以用MemoryAnalyzer.exe即我们常说的MAT工具来打开分析了;
可以清楚的看到当前堆栈里面,比较大的一些对象信息
1. Histogram可以列出内存中的对象,对象的个数以及大小。
2. Dominator Tree可以列出那个线程,以及线程下面的那些对象占用的空间。
3.Top consumers通过图形列出最大的object。
4.Leak Suspects通过MA自动分析泄漏的原因
————————————————
还为我们贴心的分析了可能内存泄漏发生的原因。。。
MAT详细的使用,这里有一篇文章:
Eclipse Memory Analyzer入门学习笔记
https://blog.csdn.net/cc907566076/article/details/79108782