pidstat —— 按进程看 CPU、内存、IO、上下文切换
pidstat —— 按进程看 CPU、内存、IO、上下文切换
分类:01 系统监控与性能 适用:Linux(sysstat 包) 一句话:
top只能看 CPU 和内存,pidstat还能按进程看磁盘 IO、缺页、上下文切换,且输出适合脚本。
1. 它解决什么问题
- 磁盘 IO 高,但
iostat只告诉我设备忙,是谁在读写? - 内存涨了,是哪个进程在缺页、在换出?
- 上下文切换异常,是哪个进程在疯狂切?
- 需要周期性采样并落盘做曲线。
2. 基本用法
pidstat 1 # 每秒一次,显示所有进程的 CPU
pidstat 1 5 # 每秒一次,共 5 次
pidstat -p 1234 1 # 只看某 PID
pidstat -p ALL 1 # 显式指定所有进程(含无活动的)
pidstat -C nginx 1 # 按命令名过滤(正则)
pidstat -u -p ALL 1 # 只看 CPU(默认就是 -u)
pidstat -h # 输出带时间戳,便于落盘
pidstat -l # 显示完整命令行
pidstat -t # 显示线程级
pidstat -G <group> # 按进程组
pidstat -U <user> # 按用户
pidstat必须带间隔参数才有统计意义,否则只输出累计值。
3. 五类核心指标
3.1 CPU(-u)
pidstat -u 1 5
UID PID %usr %system %guest %wait %CPU CPU Command
root 1234 12.00 3.00 0.00 0.00 15.00 2 java
| 列 | 含义 | 判读 |
|---|---|---|
%usr |
用户态 CPU | 应用计算 |
%system |
内核态 CPU | 系统调用、锁、内存分配 |
%guest |
虚拟机内 CPU | KVM 宿主机上才有 |
%wait |
等 CPU 的时间占比 | >10% 说明 CPU 竞争激烈,该扩容 |
%CPU |
总占用 | 单核 100% 为满 |
%wait 是很多人忽略的黄金指标:进程明明不忙,但一直在排队等 CPU。
3.2 内存(-r)
pidstat -r 1 5
UID PID minflt/s majflt/s VSZ RSS %MEM Command
root 1234 12.00 0.00 8123456 912340 5.80 java
| 列 | 含义 | 判读 |
|---|---|---|
minflt/s |
次缺页(无需 IO) | 高但正常,内存分配活跃 |
majflt/s |
主缺页(需读磁盘/swap) | 非 0 就是性能问题,说明真缺内存 |
VSZ |
虚拟内存 | 虚高正常 |
RSS |
常驻内存 | 真实占用(含共享内存,会重复计) |
%MEM |
占总内存比 |
3.3 磁盘 IO(-d)
pidstat -d 1 5
UID PID kB_rd/s kB_wr/s kB_ccwr/s iodelay Command
root 1234 0.00 8192.00 0.00 12 mysqld
| 列 | 含义 | 判读 |
|---|---|---|
kB_rd/s |
每秒读 | |
kB_wr/s |
每秒写 | 找出写盘大户 |
kB_ccwr/s |
被取消的写(脏页被覆盖,未落盘) | 高说明写了又改,浪费 |
iodelay |
IO 阻塞时钟周期(相对值) | 高说明该进程被 IO 拖住 |
iodelay单位是 clock ticks,只能横向比较不同进程,不是毫秒。
3.4 上下文切换(-w)
pidstat -w 1 5
UID PID cswch/s nvcswch/s Command
root 1234 1200.00 30.00 java
| 列 | 含义 | 判读 |
|---|---|---|
cswch/s |
自愿切换(等 IO/锁/信号量) | 高 → 锁竞争、IO 等待 |
nvcswch/s |
非自愿切换(时间片用完被抢) | 高 → CPU 不足,进程被强制让出 |
3.5 栈与线程(-s、-t)
pidstat -s 1 # 栈使用(需较新版本)
pidstat -t -p 1234 1 # 该进程的每个线程
pidstat -t -w -p 1234 1 # 线程级上下文切换,找热点线程
4. 实战场景
4.1 找出写盘最多的进程
iostat -x 1 3 /dev/sdb # 确认 sdb 忙
pidstat -d 1 5 | sort -k5 -nr | head -10
注意 pidstat -d 输出的是所有进程,按 kB_wr/s 排序即可。
4.2 判断是 CPU 不足还是锁竞争
pidstat -u -w -p <PID> 1 10
%wait高 +nvcswch/s高 → CPU 不够,扩核或降并发。%usr不高 +cswch/s很高 → 锁竞争/IO 等待,去看线程栈。
4.3 定位内存泄漏进程
pidstat -r 1 60 > /tmp/mem.log
# 观察 RSS 单调上涨且不回落
awk 'NR>3 {print $2, $7, $8}' /tmp/mem.log | sort -k3 -nr | head
4.4 留证并画曲线
pidstat -h -u -r -d -w -p ALL 5 720 > /tmp/pidstat_$(date +%F).log
# 5 秒一次,采 1 小时,带时间戳
导入 Excel/Grafana 前用 awk 清洗:
grep -v '^#' /tmp/pidstat.log | grep -v '^$' | awk '{print $1,$2,$3,$9,$10}'
4.5 线程级热点
pidstat -t -u -p <PID> 1 5
# 输出里 TID 列是线程号,配合 top -H 或 jstack 定位代码
5. 常见坑
- 不带间隔参数:输出开机以来的累计平均,看起来一切正常,是误判重灾区。
RSS会重复计算共享内存:多进程共享同一块内存时,每个进程都算一遍,总和可能超过物理内存。精确统计用smem的 PSS。%CPU单核 100% 上限:多线程进程可超过 100%(如 800%)。iodelay不是毫秒:是 clock tick 累计,只适合排序比较。- 线程数过多时输出巨大:加
-p <PID>或-C <name>收窄。 - 容器内
-p ALL看不到宿主机其他进程(PID namespace 隔离),但%CPU是相对宿主机的,会偏小。 -C是正则:-C java会匹配javac,写-C '^java$'更准。- 老版本无
%wait列:sysstat 11.5+ 才有,CentOS 7 的 10.1 没有。 - 进程消失后 PID 复用:长时间采样脚本要同时记录启动时间(
ps -o lstart)。
6. 速查表
pidstat 1 # CPU,所有进程
pidstat -u -p <PID> 1 # 单进程 CPU
pidstat -r 1 # 内存
pidstat -d 1 # 磁盘 IO
pidstat -w 1 # 上下文切换
pidstat -t -p <PID> 1 # 线程
pidstat -C '^nginx$' 1 # 按命令名
pidstat -h -u -r -d -w 5 720 # 带时间戳长采样
# 关键:%wait 高=CPU 竞争;majflt/s>0=真缺内存;nvcswch/s 高=被抢 CPU