读完这篇文,才知道小看了ps、top 命令

如何查看某 进程的CPU和MEM等信息呢?如果进程已经运行了很久了,如何才能确定真实的CPU利用率?那么 ps 和 top 命令可以妥妥的解决你的问题。

** 1. ps命令**

先来看ps命令,通过ps -aux 可以查看到进程的CPU和MEM等信息:


USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMANDroot         1  0.0  0.3 191808  3764 ?        Ss    2018   2:44 /usr/lib/systemd/systemd --switched-root --system --deserialize 21root         2  0.0  0.0      0     0 ?        S     2018   0:02 [kthreadd]root         3  0.0  0.0      0     0 ?        S     2018   5:23 [ksoftirqd/0]root         5  0.0  0.0      0     0 ?        S<    2018   0:00 [kworker/0:0H]root         7  0.0  0.0      0     0 ?        S     2018   0:00 [migration/0]root     22056  0.1  2.0 750304 20340 ?        Ssl  9月07   3:07 /usr/local/cloudmonitor/Cms*.linux-amd64......#后面内容省略


  


这里我们单独取PID为22056的Cms*进程的CPU和MEM信息。命令:ps -o %cpu %,mem -p 22056   

[16210504@izuf60jasqavbxb9efockpz ~]$ ps -o %cpu,%mem -p 22056%CPU %MEM 0.1  2.0

由上面的结果可以看到成功拿出了结果,但是这个结果其实是不准确的,使用man ps命令,查看ps统计信息的说明如下:


%cpu        %CPU      cpu utilization of the process in "##.#" format.  Currently, it is the CPU time used divided by the time the process has been running (cputime/realtime ratio), expressed as a percentage.  It will not add up to 100% unless you are lucky.                             (alias pcpu).  
%mem        %MEM      ratio of the process's resident set size  to the physical memory on the machine, expressed as a percentage.  (alias pmem).

我们可以看到ps命令统计CPU的信息是拿CPU使用的时间除以进行总运行的时间(cputime/realtime
ratio),这样就有可能出现,CPU在某个时间里利用率很高。但是因为进程已经运行了很久了,导致实际算出来的值依然是很小的,影响结果的判断。

** 2. top命令**

通常我们关注的是CPU在连续的变化情况,也就是需要CPU的切片信息。这个时候我们想要及时的统计信息就需要使用top命令了:


[16210504@izuf60jasqavbxb9efockpz ~]$ toptop - 23:03:54 up 316 days, 13:52, 13 users,  load average: 0.00, 0.01, 0.05Tasks: 159 total,   1 running, 113 sleeping,  45 stopped,   0 zombie%Cpu(s):  0.3 us,  0.7 sy,  0.0 ni, 99.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 stKiB Mem :  1016396 total,   434728 free,   133020 used,   448648 buff/cacheKiB Swap:        0 total,        0 free,        0 used.   710848 avail Mem  
  PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND22056 root      20   0  750304  20472   5612 S  0.3  2.0   3:23.00 Cms*.linu    1 root      20   0  191808   3764   1436 S  0.0  0.4   2:44.29 systemd    2 root      20   0       0      0      0 S  0.0  0.0   0:02.10 kthreadd    3 root      20   0       0      0      0 S  0.0  0.0   5:23.84 ksoftirqd/0    5 root       0 -20       0      0      0 S  0.0  0.0   0:00.00 kworker/0:0H    7 root      rt   0       0      0      0 S  0.0  0.0   0:00.00 migration/0    8 root      20   0       0      0      0 S  0.0  0.0   0:00.00 rcu_bh    9 root      20   0       0      0      0 S  0.0  0.0  42:39.12 rcu_sched

先过滤出PID为22056的Cms*进程的CPU和MEM信息。命令:top -b -p 22056 -d 1


-b : 批处理模式,可以把输出导给下一个进程-p : 打印某一个进程-d 1 : 每隔1秒打印一次

[16210504@izuf60jasqavbxb9efockpz ~]$ top -b -p 22056 -d 1top - 23:14:52 up 316 days, 14:03, 10 users,  load average: 0.00, 0.01, 0.05Tasks:   1 total,   0 running,   1 sleeping,   0 stopped,   0 zombie%Cpu(s):  2.5 us,  2.5 sy,  0.0 ni, 94.9 id,  0.1 wa,  0.0 hi,  0.0 si,  0.0 stKiB Mem :  1016396 total,   444484 free,   122968 used,   448944 buff/cacheKiB Swap:        0 total,        0 free,        0 used.   721340 avail Mem  
  PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND22056 root      20   0  750304  20472   5612 S  0.0  2.0   3:24.04 Cms*.linu  
top - 23:14:53 up 316 days, 14:03, 10 users,  load average: 0.00, 0.01, 0.05Tasks:   1 total,   0 running,   1 sleeping,   0 stopped,   0 zombie%Cpu(s):  0.0 us,  0.0 sy,  0.0 ni,100.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 stKiB Mem :  1016396 total,   444484 free,   122968 used,   448944 buff/cacheKiB Swap:        0 total,        0 free,        0 used.   721340 avail Mem  
  PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND22056 root      20   0  750304  20472   5612 S  0.0  2.0   3:24.04 Cms*.linu......  
  
16210504@izuf60jasqavbxb9efockpz ~]$ top  -p 22056 -d 1top - 23:18:05 up 316 days, 14:07, 10 users,  load average: 0.13, 0.04, 0.05Tasks:   1 total,   0 running,   1 sleeping,   0 stopped,   0 zombie%Cpu(s):  1.0 us,  0.0 sy,  0.0 ni, 99.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 stKiB Mem :  1016396 total,   444360 free,   123004 used,   449032 buff/cacheKiB Swap:        0 total,        0 free,        0 used.   721304 avail Mem  
  PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND22056 root      20   0  750304  20472   5612 S  0.0  2.0   3:24.37 Cms*.linu  
...  
[16210504@izuf60jasqavbxb9efockpz ~]$

实例:

利用top命令来完成性能数据CPU、MEM信息的需求:

_ 思路_ :统计进程10次的CPU和MEM的变化情况并输出平均值。

预计效果:


CPU  MEM0.1  2.00.1  2.1... # 共统计10次-----0.13 2.4  # 这里是平均值


  


 _ **实现:**_  

每隔1秒打印一次进程信息,共打印10次,过滤出只包含进程信息的行:命令:top -b -p 22056 -n 10 -d 1 | grep 22056


[16210504@izuf60jasqavbxb9efockpz ~]$ top -b -p 22056 -n 10 -d 1 | grep 2205622056 root      20   0  750304  20476   5616 S  0.0  2.0   3:26.70 Cms*.linu22056 root      20   0  750304  20476   5616 S  0.0  2.0   3:26.70 Cms*.linu22056 root      20   0  750304  20476   5616 S  0.0  2.0   3:26.70 Cms*.linu......# 共打印出10行

利用awk命令分别取出第9,第10段信息,对应着CPU和MEM,并用BEGAIN命令先打印出头信息。

命令:top -b -p 22056 -n 10 -d 1 | grep 22056 | awk BEGAIN{print "CPU%","MEM%"}

[16210504@izuf60jasqavbxb9efockpz ~]$ top -b -p 22056 -n 10 -d 1 | grep 22056 | awk 'BEGIN{print "CPU%","MEM%"}{print $9,$10}'CPU% MEM%

现在出现了一个现象,awk切片后的信息没有被实时打印出来,在大概过了10秒后,所有的信息被一起打印出来如下:


[16210504@izuf60jasqavbxb9efockpz ~]$ top -b -p 22056 -n 10 -d 1 | grep 22056 | awk 'BEGIN{print "CPU%","MEM%"}{print $9,$10}'CPU% MEM%#10秒后所有信息被一起打印0.0 2.01.0 2.01.0 2.00.0 2.00.0 2.00.0 2.00.0 2.00.0 2.00.0 2.00.0 2.0


  


这里要先引出另一个问题:grep和awk处于效率的考量,会缓存一批数据再输出到标准输出,就会导致即使满足匹配条件也不会即使打印出来,想要获取即时的信息,就需要使用grep --line-buffered,使grep不缓存信息,直接输出:

另外,由于最后还要算平均值,所以每次的数据都需要存在一个变量中
命令:top -b -p 22056 -n 10 -d 1 | grep 22056 --line-buffered | awk 'BEGIN{print "CPU%","MEM%"}{print $9,$10}{cpu+=$9;mem+=$10}'


[16210504@izuf60jasqavbxb9efockpz ~]$ top -b -p 22056 -n 10 -d 1 | grep 22056 --line-buffered | awk 'BEGIN{print "CPU%","MEM%"}{print $9,$10}{cpu+=$9;mem+=$10}'CPU% MEM%0.0 2.00.0 2.00.0 2.01.0 2.00.0 2.00.0 2.00.0 2.00.0 2.00.0 2.00.0 2.0


  


最后,我们我们利用awk的END,来输出分隔符,并计算最终的平均值打印出来(其中的NR表示总行数)

  


命令:top -b -p 22056 -n 10 -d 1 | grep 22056 --line-buffered | awk 'BEGIN{print "CPU%","MEM%"}{print $9,$10}{cpu+=$9;mem+=$10}END{print "------";print cpu/NR,mem/NR}'

_ 最终结果:_


 [16210504@izuf60jasqavbxb9efockpz ~]$ top -b -p 22056 -n 10 -d 1 | grep 22056 --line-buffered | awk 'BEGIN{print "CPU%","MEM%"}{print $9,$10}{cpu+=$9;mem+=$10}END{print "------";print cpu/NR,mem/NR}'CPU% MEM%0.0 2.00.0 2.00.0 2.01.0 2.00.0 2.00.0 2.00.0 2.01.0 2.00.0 2.00.0 2.0------0.2 2


  


也可以即使打印平均值信息,并用OFS指定制表符的方式进行格式化输出:  
命令:top -b -p 22056 -n 20 -d 1 | grep --line-buffered 22056 | awk 'BEGIN{OFS="\t";print"cpu","mem","avgc","avgm"}{c+=$9;m+=$10;print $9,

$10,c/NR,m/NR}'

[16210504@izuf60jasqavbxb9efockpz ~]$ top -b -p 22056 -n 20 -d 1 | grep --line-buffered 22056 | awk 'BEGIN{OFS="\t";print "cpu","mem","avgc","avgm"}{c+=$9;m+=$10;print $9,$10,c/NR,m/NR}'cpu  mem  avgc  avgm0.0  2.0  0  20.0  2.0  0  20.0  2.0  0  20.0  2.0  0  20.0  2.0  0  20.0  2.0  0  20.0  2.0  0  20.0  2.0  0  22.0  2.0  0.222222  20.0  2.0  0.2  20.0  2.0  0.181818  20.0  2.0  0.166667  20.0  2.0  0.153846  20.0  2.0  0.142857  20.0  2.0  0.133333  20.0  2.0  0.125  20.0  2.0  0.117647  20.0  2.0  0.111111  20.0  2.0  0.105263  20.0  2.0  0.1  2


                                   

  


 ** _3.  

来霍格沃兹测试开发学社,学习更多软件测试与测试开发的进阶技术,知识点涵盖web自动化测试 app自动化测试、接口自动化测试、测试框架、性能测试、安全测试、持续集成/持续交付/DevOps,测试左移、测试右移、精准测试、测试平台开发、测试管理等内容,课程技术涵盖bash、pytest、junit、selenium、appium、postman、requests、httprunner、jmeter、jenkins、docker、k8s、elk、sonarqube、jacoco、jvm-sandbox等相关技术,全面提升测试开发工程师的技术实力
QQ交流群:484590337
公众号 TestingStudio
点击获取更多信息

上一篇:密码学系列之:碰撞抵御和碰撞***collision attack


下一篇:LeetCode 735 - Asteroid Collision