我想获取 Linux 上单个进程的 CPU 和内存使用情况——我知道 PID。希望我可以每秒获取它并使用“watch”命令将其写入 CSV。我可以使用什么命令从 Linux 命令行获取此信息?
21 回答
ps -p <pid> -o %cpu,%mem,cmd
(您可以不使用“cmd”,但这可能有助于调试)。
请注意,这给出了进程在运行期间的平均 CPU 使用率。
咖啡馆答案的变体:
top -p <pid>
这会自动刷新 CPU 使用率,因此有利于监控。
ps
命令(不应使用):
top
命令(应该使用):
用于top
实时获取 CPU 使用率(当前短时间间隔):
top -b -n 2 -d 0.2 -p 6962 | tail -1 | awk '{print $9}'
会像这样回响:78.6
-b
: 批处理模式-n 2
: Number-of-iterations,使用2
因为:当你第一次运行它时,它没有以前的样本可以比较,所以这些初始值是自启动以来的百分比。-d 0.2
: 延迟时间(秒,这里是200ms)-p 6962
: 监视器-PIDtail -1
: 最后一行awk '{print $9}'
:第9列(cpu使用数)
您可以使用进程名称获取结果
ps -C chrome -o %cpu,%mem,cmd
该-C
选项允许您在不知道它的 pid 的情况下使用进程名称。
使用 pidstat(来自 sysstat -参考链接)。
例如,每 5 秒监视这两个进程 ID(12345 和 11223)使用
$ pidstat -h -r -u -v -p 12345,11223 5
启动程序并监控它
如果您想轻松地对可执行文件进行基准测试,此表单很有用:
topp() (
$* &>/dev/null &
pid="$!"
trap ':' INT
echo 'CPU MEM'
while sleep 1; do ps --no-headers -o '%cpu,%mem' -p "$pid"; done
kill "$pid"
)
topp ./myprog arg1 arg2
现在,当您按 Ctrl + C 时,它会退出程序并停止监视。样本输出:
CPU MEM
20.0 1.3
35.0 1.3
40.0 1.3
相关:https ://unix.stackexchange.com/questions/554/how-to-monitor-cpu-memory-usage-of-a-single-process
在 Ubuntu 16.04 上测试。
您可以使用top -b
并 grep 出您想要的 pid(-b
标志 top 在批处理模式下运行),或者也可以使用-p
标志并指定 pid 而不使用 grep。
正如上面 caf的回答所评论的那样, ps 和在某些情况下 pidstat 会给你 pCPU 的生命周期平均值。要获得更准确的结果,请使用 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
以下命令每 40 秒获取特定进程 (pid) 的 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
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
对于那些挣扎了一段时间想知道为什么所选答案不起作用的人:
ps -p <pid> -o %cpu,%mem
%cpu,
和之间没有空格%mem
。
要仅获取您的应用程序的内存使用情况(与它使用的共享库相反,您需要使用 Linux smaps 接口)。这个答案很好地解释了它。
(如果您使用的是 MacOS 10.10,请尝试 top 的 accumulative -c 选项:
top -c a -pid PID
(其他linux没有这个选项,用Scientific Linux el6和RHEL6试过)
ps aux|awk '{print $2,$3,$4}'|grep PID
其中第一列是 PID,第二列是 CPU 使用率,第三列是内存使用率。
ps axo pid,etime,%cpu,%mem,cmd | grep 'processname' | grep -v grep
PID - 进程 ID
etime - 进程运行/实时持续时间
%cpu - CPU 使用率
%mem - 内存使用
cmd - 命令
将 processname 替换为您要跟踪的任何进程,mysql nginx php-fpm 等...
这里的所有答案仅显示 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
这是一个很好的技巧,可以实时跟踪一个或多个程序,同时还可以查看其他工具的输出:
watch "top -bn1 -p$(pidof foo),$(pidof bar); tool"
根据@caf 的回答,这对我来说效果很好。
计算给定 PID 的平均值:
测量.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
上面列出了最消耗 CPU 和内存的进程
ps axo %cpu,%mem,command | sort -nr | head
根据@Neon 的回答,我的两分钱在这里:
pidstat -h -r -u -v -p $(ps aux | grep <process name> | awk '{print $2}' | tr '\n' ',')
基于这个答案N samples
,我们可以通过sampling period 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)
}';
为了能够评估结果,我们将顶部的输出收集到/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
请注意,我们忽略 ( tail -n +2
) top 命令的第一次执行。