分类: LINUX
2016-12-07 22:34:16
当我们遇到软件的性能问题的时候,需要对系统的CPU,内存,磁盘等方面的时候情况进行查看。其中查看CPU使用情况是首要任务。查看CPU,主要是弄清楚下面的几个问题。 1. CPU使用率是不是很高 2. 哪些进程和哪些线程在占用CPU 3. 占用CPU的任务将时间消耗在用户态还是内核态。 4. 系统的负载时多少,系统CPU是不是已经过载了。 5. 如何看到占用CPU的任务中是哪些路径的代码在占用CPU
上面的五个步骤是一种很自然的,循序渐进的,由表及里的思路。基本上弄清楚了上面的五个方面,我们就可以弄清楚CPU使用率高的具体原因。对优化程序能起到指导作用。
面对性能问题,我们第一件事情就是查看CPU使用率。查看CPU使用率的方式是大家都熟悉的top命令,但是top在多核系统中指示的是所有CPU的平均使用率,这一点大家必须理解。比如说,对于一个4核的系统,如果一个CPU的使用率是100%,其它CPU都在空闲状态,使用top命令看到的使用率可能只有25%。 另一个top命令就是top -H -p pid,这个命令能够查看某一个进程下的所有线程CPU使用率
top -H -p pid
上面的这个命令也就是查看某个进程下哪些线程占用了较多的CPU
top - 15:31:32 up 69 days, 6:09, 35 users, load average: 1.78, 3.36, 3.86 Tasks: 3 total, 0 running, 3 sleeping, 0 stopped, 0 zombie Cpu(s): 0.0% us, 0.0% sy, 0.0% ni, 99.9% id, 0.0% wa, 0.0% hi, 0.0% si Mem: 264037488k total, 261933344k used, 2104144k free, 4541060k buffers Swap: 33554428k total, 1116764k used, 32437664k free, 212254216k cached PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 134 root 20 0 22296 2072 0 S 0.0 0.0 0:00.09 ypbind 139 root 20 0 22296 2072 0 S 0.0 0.0 0:00.00 ypbind 140 root 20 0 22296 2072 0 S 0.0 0.0 0:18.59 ypbind
程序消耗CPU基本上有两种情况 1. 程序在进行大量的计算操作,比如加密操作等,这时候程序会在用户态消耗大量的CPU 2. 程序在进行很多的IO请求,比如网络收发报文,或者读写磁盘,这时候会消耗大量CPU在内核态中。
我们有如下命令可以查看进程消耗CPU是在用户态还是在内核态
vmstat 1 mpstat -P ALL 1 sar -P ALL -u 1
$vmstat 1 procs -----------memory---------- ---swap-- -----io---- --system-- ----cpu---- r b swpd free buff cache si so bi bo in cs us sy id wa 0 0 1117164 1847008 4544520 212508872 0 0 11 41 0 0 1 1 98 0 0 0 1117164 1846976 4544520 212508948 0 0 0 12 1864 3419 0 0 100 0 0 0 1117164 1847328 4544520 212508948 0 0 0 12 2210 3792 0 0 100 0 0 0 1117164 1847164 4544520 212508948 0 0 0 12 2293 3657 0 0 100 0 0 0 1117164 1846848 4544520 212508948 0 0 0 12 2946 4963 0 0 99 0 0 0 1117164 1846848 4544520 212508948 0 0 0 38020 1894 2941 0 0 100 0 0 0 1117164 1846972 4544528 212508948 0 0 0 48 401 1272 0 0 100 0
root@localhost:~# mpstat -P ALL 1 Linux 3.12.19-rt30 (localhost) 01/09/70 _ppc_ (2 CPU) 02:43:11 CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle 02:43:12 all 97.52 0.00 1.98 0.00 0.00 0.50 0.00 0.00 0.00 0.00 02:43:12 0 95.05 0.00 3.96 0.00 0.00 0.99 0.00 0.00 0.00 0.00 02:43:12 1 100.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 02:43:12 CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle 02:43:13 all 96.98 0.00 3.02 0.00 0.00 0.00 0.00 0.00 0.00 0.00 02:43:13 0 93.07 0.00 5.94 0.00 0.00 0.99 0.00 0.00 0.00 0.00 02:43:13 1 100.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 02:43:13 CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle 02:43:14 all 97.50 0.00 2.50 0.00 0.00 0.00 0.00 0.00 0.00 0.00 02:43:14 0 95.00 0.00 5.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 02:43:14 1 100.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
root@localhost:~# sar -P ALL -u 1 Linux 3.12.19-rt30 (localhost) 01/09/70 _ppc_ (2 CPU) 03:01:04 CPU %user %nice %system %iowait %steal %idle 03:01:05 all 97.00 0.00 3.00 0.00 0.00 0.00 03:01:05 0 96.00 0.00 4.00 0.00 0.00 0.00 03:01:05 1 98.00 0.00 2.00 0.00 0.00 0.00 03:01:05 CPU %user %nice %system %iowait %steal %idle 03:01:06 all 97.00 0.00 3.00 0.00 0.00 0.00 03:01:06 0 95.00 0.00 5.00 0.00 0.00 0.00 03:01:06 1 99.00 0.00 1.00 0.00 0.00 0.00
从上面的命令和方法我们大致知道了哪些CPU上面,哪些进程和线程消耗了多少CPU,并且知道消耗CPU是在用户态还是在内核态。接下去我们还想知道这么多进程在忙碌的跑着,是不是真的达到了系统的满载程度呢?对的,查看一下系统的负载,我们有如下命令查看系统负载。 1. uptime 2. sar -P ALL -q 1
root@localhost:~# sar -P ALL -q 1 Linux 3.12.19-rt30 (localhost) 01/09/70 _ppc_ (2 CPU) 03:06:06 runq-sz plist-sz ldavg-1 ldavg-5 ldavg-15 blocked 03:06:07 12 174 15.86 16.09 15.86 0 03:06:08 11 174 15.86 16.09 15.86 0 03:06:09 13 174 15.79 16.07 15.86 0 03:06:10 13 174 15.79 16.07 15.86 0
从上面命令的结果来看 1. runq-sz 表示系统中可运行的程序线程数目 2. plist-sz 表示系统中总共的进程和线程数目 3. ldavg-1 表示一分钟内系统的负载大小,也可以理解位平均可运行状态的线程数目
OK,上面的方法使我们队消耗CPU的程序有了大概的认识,最有我们要在这个程序中找到真正导致CPU忙的“罪魁祸首”,也就是我们希望找到有问题的代码具体位置,完成这个目标的方法有如下三个。 1. perf top -p pid 2. pstack pid 3. 上一篇文章中介绍的CPU call trace采样并且绘制出火焰图来,这个方法比较重量级,但是更加直观和可视化。
如何用一条命令占用CPU
while true; do a=1; done &