教你一招!Linux下排查进程占用cpu高的问题

527 阅读3分钟

大家好!我是Sean!

相信很多C++程序员都经历程序占用cpu过高的问题,这种问题,如果对代码运行逻辑足够熟悉,只靠脑子想估计定位起来也不难,但是如果是调用第三方sdk,或者团队其他人开发的库导致的cpu占用居高,就不那么容易定位了。

今天就分享一下我在工作中如何操作的!‍

如何确定程序cpu占用情况?

这个非常简单,一条命令搞定,top -p 进程pid,这样就可以:

这样就可以持续的观察你的程序的cpu占用情况,如果一直居高不下,就可能是有问题了。‍‍从图中可以看到%CPU为98.0,这已经非常非常高了。

如何查看线程级别的cpu占用情况?

方法一:

命令:

ps H -eo user,pid,ppid,tid,time,%cpu,cmd --sort=%cpu | grep 进程号

这个比较长,理解一下也不难记忆,这里我们可以看到用户、进程号、父进程号、线程号、cpu占用总时长、cpu占用率、程序名。按照cpu的值进行了升序排列,最后一个即为占用cpu最高的线程,这样就可以找到对应线程号。

图中第4列就是线程号,第5列是cpu占用时长,第6列是cpu占用率,可以看到54313线程占用CPU最高。

方法二:

命令:

top -H -p 进程号

-H  :Threads-mode operation
-p  :Monitor-PIDs

这个就很好记了,推荐用这个!一目了然,动态显示各个线程的cpu占用情况,很容易找出最高的那个。

‍‍图中%CPU列很清晰的列出了cpu的占用状况,也可以看出54313线程占用cpu最高。

细心的同学发现了,为什么这两种方法得到的数据不一样?莫非不对?其实都是对的,只是计算用的数据不同,top得到的是瞬时的cpu占用率,top数据默认3秒刷新一次,所以计算的是这3秒内线程占用CPU时长占比,而ps计算的是从启动到现在的一个时长占比,运行时间越长,就会趋近于某个固定值,感兴趣的同学可以了解一下cpu占用率的算法。

如何将问题定位到代码行级别?

通过上面的操作我们已经找到了那个搞事情的线程,但是线程长得都一个鬼样子,我们只能看到一个代表它的数字,此时需要一个建立一个线程号与具体代码的映射关联,那么就需要用到这几个查看堆栈信息的强大工具了。

gstack/pstack(c/c++程序)

命令:

gstack/pstack 进程号

这两个其实一个工具,pstack是gstack的软连接而已。

jstack(java程序)

命令:

jstack 进程号

如果线程比较多,重定向到一个文本文件吧,gstack 进程号 >gstack.txt,方便查看。这个文本文件里存放的就是线程号和调用堆栈一对一的映射,这样我们就可以很容易找到具体出问题的代码,建议多抓取几次,如果每次都是一样的调用堆栈,基本可以确定就是那块代码出的问题了。‍‍

经过这样一番操作,定位cpu占用高的问题就能迅速定位啦!

今天就分享到这里啦!感谢大家!觉得有用的话,帮忙点个赞呗~‍‍

扫码关注我的公众号,文章第一时间发布在公众号平台。