问题及原因
某个java容器cpu吃满 服务超时无法访问。
先在宿主机上top 查看最吃cpu的进程
找到进程号 进入对应的容器 并查看容器内的pid 为41
获取pid的线程信息,并找到占用CPU高的线程
#获取线程信息,并找到占用CPU高的线程
# ps -mp pid -o THREAD,tid,time | sort -rn
ps -mp 41 -o THREAD,tid,time | sort -rn > /tmp/4.txt
# vi或者cat /tmp/4.txt |head 10 找一个占用cpu比较高的线程id
将需要的线程ID转换为16进制格式
# printf "%x\n" tid
printf "%x\n" 32
# 输出正好是2b
打印线程的堆栈信息
# jstack pid |grep tid16进制 -A 30 > /tmp/5.txt
jstack 41 |grep 2b -A 30 > /tmp/5.txt
# vi或者cat /tmp/5.txt 找到02b
从进程和线程的堆栈信息可以看出是JVM的GC线程一直在占用大量CPU, 定位代码得出的结论是:Java程序连MySQL频繁new connection而且没有调用close方法,导致GC线程一直占用CPU。
查看gc和老年代回收
jstat -gcutil 41 1000
尬住 老年代回收不了 一直FGC
查看相关信息 截图给开发
jmap -histo:live 41 | more
最后排查原因是大众点评之前开源的一个做调用链路追踪的cat,后面我们开发没用,但之前已经集成在服务里面了。导致没有消费,一起往一个对象里面写数据,对象占用内存大,但又GC不掉,最后把cat去掉就好了。
参考
https://www.cnblogs.com/cnndevelop/p/11091813.html