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

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

469504 次浏览

你可以使用top -b和grep输出你想要的pid(使用-b标志在批处理模式下运行),或者也可以使用-p标志并指定pid而不使用grep。

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

(您可以省略“cmd”,但这可能有助于调试)。

注意,这给出了进程在运行期间的平均CPU使用率。

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

caf的回答的一个变体: top -p <pid> < / p >

这将自动刷新CPU使用情况,因此非常适合监控。

ps aux | awk '{print $4"\t"$11}' | sort | uniq -c | awk '{print $2" "$1" "$3}' | sort -nr

或者每个进程

ps aux | awk '{print $4"\t"$11}' | sort | uniq -c | awk '{print $2" "$1" "$3}' | sort -nr |grep mysql

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

例如,每5秒监控这两个进程id(12345和11223)的使用情况

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

(如果你使用的是MacOS 10.10,试试top的cumulative -c选项:

top -c a -pid PID

(此选项在其他linux中不可用,尝试使用Scientific linux el6和RHEL6)

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

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

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

ps aux|awk  '{print $2,$3,$4}'|grep PID

其中第一列是PID,第二列是CPU使用率,第三列是内存使用率。

ps axo pid,etime,%cpu,%mem,cmd | grep 'processname' | grep -v grep

PID -进程号

etime -进程运行/活时长

%cpu - cpu使用率

%mem -内存使用率

cmd -命令

将processname替换为任何你想跟踪的进程,mysql nginx php-fpm等等…

正如上面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

启动一个程序并监控它

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

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,程序也会因为trap: 当我的shell脚本退出时,我如何杀死后台进程/作业? . C而停止

选项是:

  • 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
)

如前所述,at: 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)
  • 如何从top中删除头文件:没有人有更好的解决方案,所以我们只是tail它:
    • https://unix.stackexchange.com/questions/471072/how-to-remove-top-commands-header < a href = " https://unix.stackexchange.com/questions/471072/how-to-remove-top-commands-header " > < / >
    • 如何屏蔽top命令的一般信息

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

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

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

ps内存测量值应该与top相同,但如果你只是在内存。

相关:

在Ubuntu 21.10上测试。

上面列出了消耗cpu和内存最多的进程

        ps axo %cpu,%mem,command | sort -nr | head

这里的所有答案都只显示了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

对于那些纠结了一段时间,想知道为什么选定的答案不管用的人:

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

%cpu,%mem之间没有空格。

这是一个很好的技巧,可以实时跟踪一个或多个程序,同时还可以查看其他工具的输出: watch "top -bn1 -p$(pidof foo),$(pidof bar); tool" < / p >

下面的命令获取特定进程(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

根据@caf的回答,这对我来说很有效。

计算给定PID的平均值:

measure.sh

times=100
total=0
for i in $(seq 1 $times)
do
OUTPUT=$(top -b -n 1 -d 0.1 -p $1 | tail -1 | awk '{print $9}')
echo -n "$i time: ${OUTPUT}"\\r
total=`echo "$total + $OUTPUT" | bc -l`
done
#echo "Average: $total / $times" | bc


average=`echo "scale=2; $total / $times" | bc`
echo "Average: $average"

用法:

# send PID as argument
sh measure.sh 3282

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

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

基于这个答案,我们可以通过使用sampling period T收集N samples来估计特定进程在特定时间内的平均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)。

我用htop

sudo apt install htop
htop

F3查找您感兴趣的进程并记住PID。用退出并再次启动htop,只显示你想要的进程

htop -p $PID