前言
如果我们自己的程序的CPU Usage
(CPU占用率
)飙升,并且居高不下,很有可能陷入了死循环。你知道怎么快速定位并解决吗?今天跟大家分享几种定位方法,希望对你有所帮助。
如何判断是否有死循环?
-
通过电脑风扇的声音猜测。
如果风扇一直响个不停,说明电脑很热。高
CPU占用率
会导致CPU
发热量增大,从而导致风扇狂响。如果听到风扇响个不停,可以打开任务管理器看看CPU占用率
是不是很高。如果发现是我们的进程导致的高CPU占用率
,那么可以进一步查看是不是有死循环。 -
通过
CPU占用率
来判断。对于多核
CPU
(尤其是性能强劲的CPU
),一个核心的满负荷运转,并不会立刻导致CPU
发热量明显增大,风扇可能不会有明显响动。这时根据风扇声音不能轻易判断出是否有死循环,但是我们可以通过CPU占用率
来判断。如果
CPU
是单核的,那么当CPU
处于满负荷运转状态,CPU占用率
会接近100%
。如果CPU
是4
核的,并且这4
个核心都处于满负荷运转状态,那么CPU占用率
会接近100%
,如果只有一个核心是满负荷运转状态,那么CPU
占用率会在25%
(100 / 4 = 25
)左右。如果我们发现某个进程的CPU占用率
居高不下,有可能是死循环了。{% note info %}
注意: 很多死循环都是busy
类型的,如果是idle
类型的死循环,上面的方法不适用。
{% endnote %}
下面介绍几个我经常使用的工具,可以比较便捷的排查此类的问题。
1. process explorer
在前面的文章里跟大家介绍过,使用process explorer
可以查看线程的调用栈
及CPU占用率
。如果程序里的某个功能迟迟不能完成,我的第一反应是,按Ctrl + Shift + Esc
打开任务管理器(我已经使用process explorer
替换了系统自带的任务管理器,所以启动的是process explorer
。如何使用process explorer
替换系统自带的任务管理器,请参考文章排错实战——使用process explorer替换任务管理器)。
启动process explorer
后,双击我们关心的进程,切换到Thread
页,在这里我们可以看到当前进程中的所有线程。双击某个线程就可以查看调用栈,在弹出的调用栈界面,点击左下角的Refresh
按钮可以刷新。
如果每次刷新都能看到某个函数,很有可能是在这个函数中出现了死循环。对照源码,也许能直接能看出原因。
使用process explorer
{% note info %}
注意: 需要正确加载调试符号才可以看到对应的函数名。
{% endnote %}
2. windbg
如果不能使用process explorer
定位到具体的原因,可以使用windbg
附加到进程中进行更深入的调查。我们需要找出哪个线程运行的时间最长,因为一般死循环的线程占用的CPU
时间会比较长。应该怎么找呢?