我想知道Linux上单个进程的CPU和内存使用情况——我知道PID。希望我每秒钟都能得到它,并使用'watch'命令将其写入CSV。我可以使用什么命令从Linux命令行中获得这些信息?


当前回答

启动一个程序并监控它

如果你想轻松地对可执行文件进行基准测试,这个表单是有用的:

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的总内存使用量,例如,上面的mib使用量约为600MiB。

如果程序完成,循环停止,我们退出topp。

或者,如果你git Ctrl + C,程序也会因为陷阱而停止:当我的shell脚本退出时,我如何杀死后台进程/作业?

选项是:

T=0.5 topp ./myprog:更改轮询间隔 O=1 topp ./myprog:不隐藏程序stdout/stderr。这对于帮助关联内存使用爆发与stdout的时间点非常有用。

ps vs top瞬时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://stackoverflow.com/a/62421136/895245,它产生类型为:


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 (-b -n1) https://askubuntu.com/questions/484510/how-to-run-top-command-1-time-and-exit https://unix.stackexchange.com/questions/60328/how-to-stream-top-snapshot-into-file询问关于 如何从顶部删除头文件:没有人有更好的解决方案,所以我们只是跟踪它: https://unix.stackexchange.com/questions/471072/how-to-remove-top-commands-header 如何压制高层的一般信息

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

Ctrl + C不退出上面的命令,不确定为什么陷阱退出不像ps那样工作。我必须杀死Ctrl + \命令,然后这不会杀死继续在后台运行的进程本身,这意味着如果它是一个像服务器一样的无限循环,我必须ps aux,然后杀死它。 当基准测试程序退出时,not自动退出

也许比我更懂外壳的人能找到解决办法。

Ps内存测量应该与top相同,但如果你只是在内存之后。

相关:

检索Linux上单个进程的CPU使用情况和内存使用情况? https://unix.stackexchange.com/questions/554/how-to-monitor-cpu-memory-usage-of-a-single-process

在Ubuntu 21.10上测试。

其他回答

要获得应用程序的内存使用情况(而不是它使用的共享库),需要使用Linux smaps接口。这个答案很好地解释了这一点。

根据这个答案,我们可以通过收集N个样本,采样周期为T来估计特定进程在特定时间内的平均CPU和内存利用率,如下所示:

N=3;
T=1;
PROCESS_NAME="my_proc";

top -b -c -n $(let tmp=N+1; echo $tmp) -d ${T} -p $(pgrep ${PROCESS_NAME}) | 
grep ${PROCESS_NAME} |  
tee /var/tmp/foo.log |
tail -n +2 | 
awk -v N=$N 'BEGIN{
                c=0; 
                m=0
            }{
                c=c+$9; 
                m=m+$10
            }END{
                printf("%s %s\n", c/N, m/N) 
            }';

为了能够计算结果,我们将top的输出收集到/var/tmp/foo.log文件中。预期输出是这样的:

2.33333 6.9

以及日志文件的内容:

196918 root      20   0   24.4g   1.3g 113872 S   0.0   6.9  39:58.15 my_proc
196918 root      20   0   24.4g   1.3g 113872 S   2.0   6.9  39:58.17 my_proc
196918 root      20   0   24.4g   1.3g 113872 S   3.0   6.9  39:58.20 my_proc
196918 root      20   0   24.4g   1.3g 113872 S   2.0   6.9  39:58.22 my_proc

注意,我们忽略了top命令的第一次执行(tail -n +2)。

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

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

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

这里的所有答案都只显示了PID的内存百分比。

下面是一个如何获取所有apache进程的rss内存使用KB的例子,如果你只想查看特定的PID,将“grep apache”替换为“grep PID”:

watch -n5 "ps aux -y | grep apache | awk '{print \$2,\$6}'"

这个打印:

Every 5.0s: ps aux -y | grep apache | awk '{print $2,$6}'                                                                                                                                                                                                          
Thu Jan 25 15:44:13 2018

12588 9328
12589 8700
12590 9392
12591 9340
12592 8700
12811 15200
15453 9340
15693 3800
15694 2352
15695 1352
15697 948
22896 9360

CPU %:

watch -n5 "ps aux -y | grep apache | awk '{print \$2,\$3,\$6}'"

输出:

Every 5.0s: ps aux -y | grep apache | awk '{print $2,$3,$6}'                                                                                                                                                                                                       
Thu Jan 25 15:46:00 2018

12588 0.0 9328
12589 0.0 8700
12590 0.0 9392
12591 0.0 9340
12592 0.0 8700
12811 0.0 15200
15453 0.0 9340
15778 0.0 3800
15779 0.0 2352
15780 0.0 1348
15782 0.0 948
22896 0.0 9360

根据@Neon的回答,我的观点是:

pidstat -h -r -u -v -p $(ps aux | grep <process name> | awk '{print $2}' | tr '\n' ',')