在Linux上检索单个进程的CPU使用率和内存使用率?

226

我希望从Linux的命令行获取单个进程的CPU和内存使用情况,我已经知道该进程的PID。希望每秒钟都能够获取并使用'watch'命令将其写入CSV。请问我可以使用什么命令来获取这些信息?


16
适合发布在SuperUser上。 - Richard
我们能使用gdb来调用getpid和top -p <该pid>吗? - mja
22个回答

299
ps -p <pid> -o %cpu,%mem,cmd

(您可以省略 "cmd",但在调试时可能会有帮助)。

请注意,这会给出进程运行时间内的平均 CPU 使用率。


6
假设如果您关心某个进程的内存使用情况并像这样监视它,那么它使用的内存量很大,因此由于共享映射而产生的额外几兆字节不是问题。 - caf
5
@Chaitanya: 通过管道运算符 | 将其输入到 tail -n +2 中。tail -n +2 的作用是从第二行开始显示输出内容,以此跳过第一行的标题或其他非必要信息。 - caf
13
或者您可以使用--noheader。 - hexacyanide
57
请记住,%cpu指的是进程运行期间使用的CPU时间与实际运行时间的比率(cputime/realtime比率),以百分比表示(请参见ps命令的man手册)。这不是实时CPU使用率。它可能与top显示的结果非常不同。 - xebeche
16
如上面Xebeche所说,ps -e -o pcpu,args将显示进程的整个生命周期内的CPU平均值,如果是长时间运行的进程,显然不是您想要的结果。 - Alex F
显示剩余9条评论

80

以下是类似于 caf的答案 的变体:

top -p <pid>

这个命令会自动刷新CPU使用情况,非常适合用来监测。


5
pgrep 配合使用效果很好:top -p $(pgrep 进程名) - Matthias Braun
顶部:错误的pid进程名称 - alper
@MatthiasBraun 应该是 top -p $(pgrep -d',' 进程名称) 请参考 https://dev59.com/BWoy5IYBdhLWcg3wMLSj#8710740 - alper

70

ps命令(不应使用):

top命令(应使用):

使用top实时获取CPU使用情况(当前短时间间隔):

top -b -n 2 -d 0.2 -p 6962 | tail -1 | awk '{print $9}'

将输出类似:78.6


3
这是获取当前CPU使用率的最准确答案,而不是进程生命周期内的平均值。 - Ted Feng
1
警告:列顺序取决于您的~/.toprc,请参见下面的pidstat - KJ7LNW
这只返回%CPU。 - alper

44

您可以通过进程名称获取结果,使用

ps -C chrome -o %cpu,%mem,cmd

-C 选项允许您在不知道进程 ID 的情况下使用进程名称。


如何同时包含PID?我尝试了%pid、$PID、pid和PID,但都没有成功。 - Arnold Roa
@ArnoldRoa 只需要使用 pidps -C chrome -o pid,%cpu,%mem,cmd - Taha
这在Unix中不起作用。 - alper

42

使用pidstat(来自sysstat-请参考链接)。

例如,要每5秒监视这两个进程ID(12345和11223),请使用:

$ pidstat -h -r -u -v -p 12345,11223 5

3
感谢您指出 pidstat 这个很棒的命令!它对于编写脚本也非常方便。 - fduff
pidstat also gives a nice average. just a shame i have not found a more elegant way of pidstat -u 1 10 | grep ^Average | sort -r -n -b -k 8,8 - northern-bradley

22

启动程序并监控

如果您想轻松地对可执行文件进行基准测试,则此表单非常有用:

topp() (
  if [ -n "$O" ]; then
    $* &
  else
    $* &>/dev/null &
  fi
  pid="$!"
  trap "kill $pid" SIGINT
  o='%cpu,%mem,vsz,rss'
  printf '%s\n' "$o"
  i=0
  while s="$(ps --no-headers -o "$o" -p "$pid")"; do
    printf "$i $s\n"
    i=$(($i + 1))
    sleep "${T:-0.1}"
  done
)

使用方法:

topp ./myprog arg1 arg2

输出示例:

%cpu,%mem,vsz
0  0.0  0.0 177584
1  0.0  0.1 588024
2  0.0  0.1 607084
3  0.0  0.2 637248
4  0.0  0.2 641692
5 68.0  0.2 637904
6 80.0  0.2 642832

其中vsz是以KiB为单位的总内存使用量,例如上面的例子中使用了约600MiB。

如果您的程序执行完毕,循环将停止并退出topp

或者,如果您按下Ctrl + C,则由于trap,程序也会停止:如何在shell脚本退出时杀死后台进程/作业?

选项包括:

  • T=0.5 topp ./myprog:更改轮询间隔
  • O=1 topp ./myprog:不隐藏程序的标准输出/错误输出。这对于帮助确定内存使用情况何时突发stdout非常有用。

pstop在瞬时CPU%使用方面的区别

请注意,上面ps给出的CPU使用率不是“瞬时”的(即在过去的N秒内),而是整个进程生命周期的平均值,如此处所述:https://unix.stackexchange.com/questions/58539/top-and-ps-not-showing-the-same-cpu-result 但是,ps的内存测量应该是可以的。

该线程以及如何从shell确定当前CPU利用率?建议Linux内核不存储任何更多的中间使用统计信息,因此唯一的方法是轮询并计算前一个周期的使用情况,这就是top所做的。

因此,如果我们想要那样做,我们可以使用top -n1而不是ps

toppp() (
  $* &>/dev/null &
  pid="$!"
  trap exit SIGINT
  i=1
  top -b n1 -d "${T:-0.1}" -n1 -p "$pid"
  while true; do top -b n1 -d "${T:-0.1}" -n1 -p "$pid"  | tail -1; printf "$i "; i=$(($i + 1)); done
)

如在https://dev59.com/5nM_5IYBdhLWcg3wzmgw#62421136中提到的那样,它会产生以下类型的输出:


top - 17:36:59 up  9:25, 12 users,  load average: 0.32, 1.75, 2.21
Tasks:   1 total,   1 running,   0 sleeping,   0 stopped,   0 zombie
%Cpu(s): 13.4 us,  2.5 sy,  0.0 ni, 84.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
MiB Mem :  31893.7 total,  13904.3 free,  15139.8 used,   2849.7 buff/cache
MiB Swap:      0.0 total,      0.0 free,      0.0 used.  16005.5 avail Mem

    PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
 706287 ciro      20   0  590436  40352  20568 R 106.7   0.1   0:00.16 node
 706287 ciro      20   0  607060  57172  21340 R 126.7   0.2   0:00.35 node
1  706287 ciro      20   0  642008  80276  21812 R 113.3   0.2   0:00.52 node
2  706287 ciro      20   0  641676  93108  21812 R 113.3   0.3   0:00.70 node
3  706287 ciro      20   0  647892  99956  21812 R 106.7   0.3   0:00.87 node
4  706287 ciro      20   0  655980 109564  21812 R 140.0   0.3   0:01.09 node

一些相关的帖子:

我唯一的问题是top不太适合交互式使用:

  • Ctrl + C不能退出上述命令,不确定为什么trap exitps一样无效。我必须杀掉命令Ctrl + \,但这并不会杀掉进程本身,进程继续在后台运行,这意味着如果它是一个无限循环的服务器之类的东西,我必须ps aux,然后杀掉它。
  • 当基准测试程序退出时,top不会自动退出

也许比我更精通shell的人可以为这些问题找到解决方案。

ps的内存测量应该与top相同,但如果您只关注内存,则使用ps

相关帖子:

在Ubuntu 21.10上测试通过。


这是一个Bash函数吗?我无法使其工作。 - alper
@alper 是的。现在在Ubuntu 22.04上进行了测试,使用命令 toppp stress-ng --vm 8 --vm-bytes 80% -t 5。你遇到了什么错误? - Ciro Santilli OurBigBook.com
啊,我当时在使用 zsh,所以无法使其正常工作。 - alper
1
@pglpm这是因为我有时会在不同网站之间复制答案,忘记更新相关部分。但至少它仍然是真实的,考虑到相关性的反身性。 - Ciro Santilli OurBigBook.com
1
我也发生过几次,最后一刻才注意到 :) 我相信没有读者陷入了无限引用循环中 :D 顺便说一句,谢谢你提供的出色信息性答案!(我指的是对原帖的回答) - pglpm
显示剩余4条评论

6

正如上面caf的答案所评论的一样,ps并且在某些情况下pidstat将给出pCPU的生命周期平均值。要获得更准确的结果,请使用top。如果您需要运行一次top,则可以运行:

top -b -n 1 -p <PID>

或仅用于处理数据和标题:

top -b -n 1 -p <PID> | tail -3 | head -2

没有头部信息:

top -b -n 1 -p <PID> | tail -2 | head -1

5

您可以使用top -b命令,并使用grep命令筛选出所需的pid(使用-b标志,top以批处理模式运行),或者使用-p标志并指定pid而无需使用grep。


4

对于那些为什么选择的答案不起作用而苦苦挣扎的人:

ps -p <pid> -o %cpu,%mem

%cpu,%mem之间不要有空格。


4
以下命令可获取特定进程(pid)每40秒的CPU和内存使用率平均值。
pidstat 40 -ru -p <pid>

以下是我的情况输出(前两行为CPU使用情况,后两行为内存使用情况):

02:15:07 PM       PID    %usr %system  %guest    %CPU   CPU  Command
02:15:47 PM     24563    0.65    0.07    0.00    0.73     3  java

02:15:07 PM       PID  minflt/s  majflt/s     VSZ    RSS   %MEM  Command
02:15:47 PM     24563      6.95      0.00 13047972 2123268   6.52  java

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接