GC 的魔鬼和jstack的魔法
2020-01-17 本文已影响0人
NazgulSun
线上服务宕机
最近一段时间有大量新的数据进入底层数据库,服务里有定时任务刷新缓存。
结果某一天突然系统变得很慢,以至于失去响应
观察现象
cpu 持续的增加,重启之后,短时间内达到400%
内存稳定在8g,rancher 配置的最大内存是32G
如何解刨
问题是由于cpu太高,但是到底为何cpu 太高呢?
排查了各个组件,以及使用多线程的情况,都没有结果。
能否确定到底是哪个线程把cpu 打上去了?
jstack 利器。
首先 通过jps 获取 java pid,
然后通过 top -Hp pid 来查看 进程中 线程的分布,
我们看到 有 几十个线程都在使用cpu,占比达到8%,把rancher 容器的资源给占满。
对于一个 线程 tid = 60,我们通过 printf %x 打印16进制,44
然后通过 jstack -l pid |grep 0x44, 来抓取到具体的某一个线程。
发现是44 对应的是 gc线程, 一直在运行,把cpu打满。
配置项的错误
docker 给的限制是32G,而我们的程序为啥没有应用。
最后发现程序启动项传递了默认参数,为8G, 所以限制了内存使用情况。
由于新增的数据太大,刷新的时候load 数据变多,使得原有内存不够用,而持续做GC,造成了cpu打满。
程序失去响应。