top —— 实时进程与系统负载

运维工具手册 01-系统监控与性能 4.0 KB 原文

top —— 实时进程与系统负载

分类:01 系统监控与性能 适用:所有 Linux(procps-ng)。CentOS 7 为 3.3.10,Ubuntu 22.04 为 3.3.17,较新发行版为 4.x 一句话:系统"感觉慢"时第一个敲的命令,能同时看到负载、CPU、内存、进程。

1. 它解决什么问题

  • 现在到底忙不忙?谁在忙?忙在 CPU、内存还是 IO?
  • 某个进程吃了多少内存、跑了多久、是否僵尸。
  • 不装任何额外软件(几乎必然已装)就能给出第一手现场。

2. 快速上手

top                      # 默认 3 秒刷新
top -d 1                 # 1 秒刷新
top -n 1 -b              # 批处理模式输出一次,用于脚本/日志
top -b -n 1 -o %CPU | head -20        # 按 CPU 排序取前 20
top -p 1234,5678         # 只看指定 PID
top -u nginx             # 只看某用户(-U 按 UID)
top -H -p 1234           # 看该进程的所有线程

写入文件留证:

top -b -n 1 -d 1 > /tmp/top_$(date +%F_%H%M).log

3. 界面怎么读

3.1 头部五行

top - 10:21:33 up 12 days,  3:07,  2 users,  load average: 0.82, 1.35, 2.10
Tasks: 231 total,   2 running, 229 sleeping,   0 stopped,   0 zombie
%Cpu(s):  3.1 us,  1.2 sy,  0.0 ni, 94.8 id,  0.9 wa,  0.0 hi,  0.0 si,  0.0 st
MiB Mem :  15884.0 total,    612.3 free,   4210.5 used,  11061.2 buff/cache
MiB Swap:   4096.0 total,   4096.0 free,      0.0 used.  11001.3 avail Mem
字段 含义 判读要点
load average 1/5/15 分钟平均活跃进程数(含不可中断) 与逻辑核数比:等于核数≈满载,持续 >2×核数要处理
running 正在跑或可跑的进程数 长期远小于核数但负载高 → 卡在 IO
zombie 僵尸进程 有值说明父进程没回收,查 ps -eo stat,ppid,pid,cmd | grep ^Z
us 用户态 CPU 应用在算
sy 内核态 CPU 系统调用多、上下文切换多、也可能是被攻击
wa 等 IO 完成 >20% 且持续 → 磁盘/网络存储瓶颈
si / so 换入/换出 非 0 就是内存不足,性能会断崖
st 被虚拟化层偷走的时间 云主机 >5% 说明宿主机超卖,找云厂商
buff/cache 内核缓存 这部分可回收,不算真占用
avail Mem 估算可用内存 判断"内存够不够"看这个,不是看 free

关键:Linux 会尽量用内存做缓存,free 很小是正常现象。真正要盯的是 avail Mem 和 si/so。

3.2 进程区

列 含义 注意
PID / PPID 进程号 / 父进程号 杀进程前先看 PPID,否则会被守护进程拉起
USER 运行用户 判断是否以 root 跑业务
PR / NI 优先级 / nice 值 NI 为负是人为提权,正常业务不该有
VIRT 虚拟内存总量 包含映射但未使用的,虚高正常(JVM 尤其)
RES 常驻物理内存 真实占用,排查内存看这个
SHR 共享内存 含 tmpfs、共享库
S 状态 R 运行、S 可中断睡眠、D 不可中断(IO 卡住)、Z 僵尸、T 停止
%CPU CPU 占比 按单核算:4 核跑满一个核显示 100%,全跑满显示 400%
%MEM 物理内存占比 基于 total,非 avail
TIME+ 累计 CPU 时间 精度到 0.01 秒
COMMAND 命令 按 c 可切换显示完整命令行

4. 常用交互键

键 作用
P / M / T 按 CPU / 内存 / 运行时间排序(大写)
c 显示完整命令行(排障必按)
H 显示/隐藏线程
1 展开每个核的 CPU 使用率(判断是否单核打满)
i 隐藏空闲进程
u 按用户过滤
f 进入字段管理,增删列
k 杀进程(会问 PID 和信号)
r renice 调整优先级
z 彩色显示
W 保存当前配置到 ~/.toprc
q 退出

5. 实战场景

5.1 判断是不是单核被打满

top        # 按 1 展开

若某个核 100%、其他空闲,而整体 id 很高:应用是单线程瓶颈,加机器没用,要改代码或拆进程。

5.2 找到吃内存的真凶

top -b -n 1 -o %MEM | head -15
# 再核对真实占用(RES 可能含共享内存,重复计算)
smem -rk | head -15        # 需装 smem,按 PSS 统计更准

5.3 进程处于 D 状态(杀不掉)

D 状态的进程 kill -9 也无效,因为它卡在内核态等 IO。

ps -eo pid,stat,wchan:30,cmd | awk '$2 ~ /D/'
cat /proc/<PID>/stack          # 需要 root,看内核栈

处理方向是修 IO(NFS 挂死、磁盘故障、ceph 异常),不是杀进程。

5.4 脚本里取某个指标

# 取 1 分钟负载
top -b -n 1 | awk '/load average/ {print $(NF-2)}'

# 取内存可用
top -b -n 1 | awk '/MiB Mem/ {print $6}'

更稳的做法是读 /proc/loadavg、/proc/meminfo,不依赖 top 的输出格式(各版本会变)。

6. 常见坑

  1. %CPU 加起来能超过 100%:多核机器上单个进程上限是 100%×核数,看到 780% 不是 bug。
  2. VIRT 大不等于内存泄漏:JVM、Go 程序、glibc arena 都会预留大量虚拟地址。
  3. free 小不是内存不足:看 avail Mem。真要释放缓存才用 echo 3 > /proc/sys/vm/drop_caches(生产慎用,会掉性能)。
  4. load average 含 IO 等待:Linux 的 load 统计包含 D 状态进程,负载高但 CPU 空闲就是 IO 问题。
  5. CentOS 7 头部显示 KiB Mem,新版本显示 MiB Mem,脚本解析时注意单位。
  6. top 自身也吃 CPU:高频刷新(-d 0.1)在故障机上会加剧问题,排障用 1~3 秒即可。
  7. 容器里 top 看到的是宿主机全部进程和内存:容器内监控要用 lxcfs 或看 cgroup 限额。
  8. k 杀进程默认发 SIGTERM,杀不掉再 kill -9 <PID>,服务进程优先 systemctl stop。

7. 速查表

top -d 1                       # 1 秒刷新
top -b -n 1 -o %CPU            # 批处理按 CPU 排序
top -H -p <PID>                # 看线程
top -p <PID> -d 1              # 盯住单进程
top -u <user>                  # 按用户过滤

# 交互:P 排序CPU / M 排序内存 / c 全命令 / 1 分核 / H 线程 / k 杀 / W 保存

# 等价替代
ps -eo pid,ppid,pcpu,pmem,rss,stat,etime,cmd --sort=-pcpu | head
cat /proc/loadavg