前面说到我们在做压力测试的时候,竟然把整个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

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐