系统监控工具指南 / 第2章:top详解
第2章:top详解
2.1 top概述
什么是top
top(Table of Processes)是Linux系统自带的实时进程监控工具,能够动态显示系统中各个进程的资源占用状况。
为什么学top
- 无需安装 - 所有Linux发行版默认自带
- 轻量高效 - 资源消耗极低
- SSH友好 - 纯文本界面,远程管理必备
- 功能强大 - 排序、过滤、信号发送
2.2 启动与基本界面
启动方式
# 直接启动
top
# 常用启动参数
top -d 5 # 5秒刷新一次
top -n 10 # 刷新10次后退出
top -p 1234,5678 # 只监控指定PID
top -u username # 只监控指定用户
top -bn1 # 批处理模式,刷新1次(适合脚本)
界面解读
top - 14:32:15 up 10 days, 3:21, 2 users, load average: 0.52, 0.58, 0.59
Tasks: 215 total, 2 running, 213 sleeping, 0 stopped, 0 zombie
%Cpu(s): 5.2 us, 2.1 sy, 0.0 ni, 92.3 id, 0.3 wa, 0.0 hi, 0.1 si, 0.0 st
MiB Mem : 16384.0 total, 8192.0 free, 4096.0 used, 4096.0 buff/cache
MiB Swap: 8192.0 total, 8192.0 free, 0.0 used. 11264.0 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1234 root 20 0 512340 65432 12340 S 5.0 0.4 1:23.45 nginx
5678 mysql 20 0 1234567 234567 23456 S 3.2 1.4 12:34.56 mysqld
头部信息详解
第一行:系统概况
| 字段 | 含义 | 示例 |
|---|---|---|
14:32:15 | 当前时间 | 24小时制 |
up 10 days | 系统运行时间 | 10天3小时21分 |
2 users | 登录用户数 | 2个终端连接 |
load average | 系统负载 | 1分钟/5分钟/15分钟平均值 |
负载解读:
load average: 0.52, 0.58, 0.59
│ │ │
│ │ └── 15分钟平均负载
│ └──────── 5分钟平均负载
└────────────── 1分钟平均负载
负载与CPU核心数的关系:
| 负载值 | 4核CPU | 含义 |
|---|---|---|
| 0.5 | 12.5% | 空闲 |
| 2.0 | 50% | 正常 |
| 4.0 | 100% | 满载 |
| 8.0 | 200% | 过载,有进程等待 |
第二行:任务统计
| 字段 | 含义 |
|---|---|
215 total | 进程总数 |
2 running | 运行中进程数 |
213 sleeping | 睡眠进程数 |
0 stopped | 停止进程数 |
0 zombie | 僵尸进程数 |
僵尸进程处理:
# 查找僵尸进程
ps aux | grep 'Z'
# 查找僵尸进程的父进程
ps -eo pid,ppid,stat,cmd | grep 'Z'
# 杀死父进程(僵尸进程会被init接管)
kill -9 父进程PID
第三行:CPU使用率
| 字段 | 含义 | 说明 |
|---|---|---|
us | 用户空间占用 | 应用程序消耗 |
sy | 内核空间占用 | 系统调用消耗 |
ni | 调整过优先级的进程 | nice值修改的进程 |
id | 空闲百分比 | 越高越空闲 |
wa | IO等待 | 磁盘或网络IO |
hi | 硬件中断 | 硬件设备请求 |
si | 软件中断 | 软件请求 |
st | 虚拟机偷取时间 | 虚拟化环境特有 |
CPU瓶颈判断:
# IO瓶颈
# 特征:wa值高
%Cpu(s): 10.0 us, 5.0 sy, 0.0 ni, 20.0 id, 65.0 wa
# CPU瓶颈
# 特征:us或sy值高,id值低
%Cpu(s): 85.0 us, 10.0 sy, 0.0 ni, 5.0 id, 0.0 wa
# 虚拟化资源争抢
# 特征:st值高
%Cpu(s): 30.0 us, 10.0 sy, 0.0 ni, 40.0 id, 0.0 wa, 0.0 hi, 0.0 si, 20.0 st
第四/五行:内存使用
| 字段 | 含义 |
|---|---|
total | 物理内存总量 |
free | 空闲内存 |
used | 已使用内存 |
buff/cache | 缓冲/缓存 |
avail Mem | 可用内存(含可回收缓存) |
内存解读:
MiB Mem : 16384.0 total, 8192.0 free, 4096.0 used, 4096.0 buff/cache
MiB Swap: 8192.0 total, 8192.0 free, 0.0 used. 11264.0 avail Mem
重要: Linux会将空闲内存用作缓存,这是正常行为!真正需要关注的是:
avail Mem- 实际可用内存- Swap使用量 - 如果持续增长说明内存不足
2.3 进程列表字段
字段详解
| 字段 | 含义 | 说明 |
|---|---|---|
PID | 进程ID | 唯一标识符 |
USER | 进程所有者 | 启动进程的用户 |
PR | 优先级 | rt表示实时进程 |
NI | nice值 | -20到19,越小优先级越高 |
VIRT | 虚拟内存 | 进程申请的总内存 |
RES | 常驻内存 | 实际使用的物理内存 |
SHR | 共享内存 | 与其他进程共享的内存 |
S | 进程状态 | R/S/D/Z/T |
%CPU | CPU使用率 | 多核可能超过100% |
%MEM | 内存使用率 | 占总内存百分比 |
TIME+ | CPU时间 | 进程累计CPU使用时间 |
COMMAND | 命令名 | 进程启动命令 |
进程状态说明
| 状态 | 含义 | 说明 |
|---|---|---|
R | Running | 运行中或可运行 |
S | Sleeping | 可中断睡眠(等待事件) |
D | Disk Sleep | 不可中断睡眠(通常等待IO) |
Z | Zombie | 僵尸进程(已终止但未被回收) |
T | Stopped | 被信号停止 |
t | Tracing Stop | 被调试器停止 |
VIRT/RES/SHR关系
┌─────────────────────────────────────────┐
│ VIRT (虚拟内存) │
│ ┌─────────────────────────────────┐ │
│ │ RES (常驻内存) │ │
│ │ ┌─────────────┐ ┌───────────┐ │ │
│ │ │ 私有内存 │ │ SHR(共享) │ │ │
│ │ │ (实际占用) │ │ │ │ │
│ │ └─────────────┘ └───────────┘ │ │
│ └─────────────────────────────────┘ │
└─────────────────────────────────────────┘
关键指标:
- RES 是真正占用的物理内存
- SHR 可能被其他进程共享,实际占用更少
- VIRT 包含申请但未使用的内存
2.4 交互命令
排序操作
| 按键 | 功能 | 说明 |
|---|---|---|
P | 按CPU排序 | 默认排序方式 |
M | 按内存排序 | 查找内存大户 |
N | 按PID排序 | 按进程号 |
T | 按时间排序 | 按累计CPU时间 |
R | 反转排序 | 升序/降序切换 |
显示控制
| 按键 | 功能 |
|---|---|
1 | 显示/隐藏每个CPU核心 |
t | 切换CPU显示模式 |
m | 切换内存显示模式 |
l | 显示/隐藏负载行 |
t | 显示/隐藏任务行 |
1 | 显示/隐藏CPU行 |
进程管理
| 按键 | 功能 | 说明 |
|---|---|---|
k | 杀死进程 | 输入PID和信号 |
r | 重新设置优先级 | 输入PID和nice值 |
d | 修改刷新间隔 | 输入秒数 |
信号列表
| 信号 | 编号 | 作用 |
|---|---|---|
| SIGTERM | 15 | 优雅终止(默认) |
| SIGKILL | 9 | 强制杀死 |
| SIGHUP | 1 | 重新加载配置 |
| SIGSTOP | 19 | 暂停进程 |
| SIGCONT | 18 | 继续运行 |
其他命令
| 按键 | 功能 |
|---|---|
h | 显示帮助 |
q | 退出top |
W | 保存当前配置 |
c | 显示完整命令行 |
i | 只显示活跃进程 |
V | 树状视图 |
H | 显示线程 |
u | 按用户过滤 |
2.5 实用技巧
技巧1:查找CPU占用最高的进程
# 交互模式
# 启动top后按P(大写)
# 脚本模式
top -bn1 | head -20
# 更精确的排序
top -bn1 -o %CPU | head -20
技巧2:查找内存占用最高的进程
# 交互模式
# 启动top后按M(大写)
# 脚本模式
top -bn1 -o %MEM | head -20
技巧3:监控特定进程
# 监控特定PID
top -p 1234
# 监控多个PID
top -p 1234,5678,9012
# 监控特定用户
top -u mysql
# 监控特定命令
top -bn1 | grep nginx
技巧4:批量输出(适合脚本)
# 输出一次,适合脚本处理
top -bn1
# 输出5次,每次间隔2秒
top -bn5 -d 2
# 输出到文件
top -bn1 > top_output.txt
# 格式化输出
top -bn1 | awk 'NR>7 {print $1, $9, $10, $12}'
技巧5:查看线程
# 方法1:top中按H
top
# 按H显示线程
# 方法2:使用-H参数
top -H
# 方法3:查看特定进程的线程
top -H -p 1234
技巧6:显示完整命令
# 方法1:top中按c
top
# 按c显示完整命令
# 方法2:使用-c参数
top -c
技巧7:自定义显示字段
# 进入top后按f
# 使用上下箭头选择字段
# 按空格切换显示/隐藏
# 按s设置排序字段
# 按q退出设置
2.6 高级用法
2.6.1 配置文件
top的配置文件保存在:
~/.toprc # 用户级配置
/etc/toprc # 系统级配置
保存当前配置:
# 在top中按W(大写)
# 配置将保存到~/.toprc
配置文件示例:
# ~/.toprc
top's Config File (Linux processes with windows)
Id:a, Mode_altscr=0, Mode_irixps=1, Delay_time=3.000, Curwin=0
Def fieldscur=AEHIOQTWKNMbcdfgjplrsuvyzX
winflags=62777, sortindx=10, maxtasks=0
graph_cpus=0, graph_mems=0, double_up=0
combine_cpus=0, cpu_in_row=2
tree_view=0, tree_sort=0, tree collapsed=1
2.6.2 多窗口模式
# 启动top后
# 按A切换到多窗口模式
# 按a切换窗口
# 按G重命名窗口
窗口布局:
┌─────────────────────────────────┐
│ 1:Def - 系统概览 │
├─────────────────────────────────┤
│ 2:Job - 任务列表 │
├─────────────────────────────────┤
│ 3:Mem - 内存详情 │
├─────────────────────────────────┤
│ 4:Usr - 用户统计 │
└─────────────────────────────────┘
2.6.3 树状视图
# 启动top后按V
# 显示进程的父子关系
树状视图示例:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1 root 20 0 169452 13184 8480 S 0.0 0.1 0:03.45 systemd
567 root 20 0 24340 9876 6543 S 0.0 0.1 0:01.23 `- systemd-journal
678 root 20 0 28456 12345 8765 S 0.0 0.1 0:00.45 `- systemd-udevd
1234 www-data 20 0 512340 65432 12340 S 0.5 0.4 1:23.45 `- nginx
1235 www-data 20 0 512340 65432 12340 S 0.3 0.4 0:45.67 `- nginx
1236 www-data 20 0 512340 65432 12340 S 0.2 0.4 0:34.56 `- nginx
2.6.4 过滤显示
# 按用户过滤
# 启动top后按u,输入用户名
# 只显示活跃进程
# 启动top后按i
# 按命令名过滤(结合grep)
top -bn1 | grep nginx
2.7 脚本化应用
2.7.1 监控脚本示例
#!/bin/bash
# monitor.sh - 系统监控脚本
LOG_FILE="/var/log/system_monitor.log"
while true; do
TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')
# 获取系统负载
LOAD=$(uptime | awk -F'load average:' '{print $2}' | tr -d ' ')
# 获取CPU使用率
CPU_IDLE=$(top -bn1 | grep "Cpu(s)" | awk '{print $8}' | cut -d'.' -f1)
CPU_USED=$((100 - CPU_IDLE))
# 获取内存使用率
MEM_INFO=$(free -m | awk 'NR==2{printf "%.1f %.1f %.1f", $3*100/$2, $3, $2}')
# 获取磁盘使用率
DISK_USAGE=$(df -h / | awk 'NR==2{print $5}' | tr -d '%')
# 记录日志
echo "$TIMESTAMP | Load: $LOAD | CPU: ${CPU_USED}% | Memory: $MEM_INFO | Disk: ${DISK_USAGE}%" >> $LOG_FILE
# 检查阈值并告警
if [ $CPU_USED -gt 90 ]; then
echo "ALERT: CPU usage is ${CPU_USED}%" | mail -s "CPU Alert" admin@example.com
fi
sleep 60
done
2.7.2 获取特定进程信息
#!/bin/bash
# get_process_info.sh
PROCESS_NAME=$1
if [ -z "$PROCESS_NAME" ]; then
echo "Usage: $0 <process_name>"
exit 1
fi
# 获取进程信息
top -bn1 | grep "$PROCESS_NAME" | head -5
# 获取详细信息
ps aux | grep "$PROCESS_NAME" | grep -v grep
2.7.3 性能数据采集
#!/bin/bash
# collect_perf.sh
OUTPUT_FILE="perf_data_$(date +%Y%m%d_%H%M%S).csv"
# CSV头
echo "Timestamp,CPU_Used,Memory_Used,Load_1m,Load_5m,Load_15m" > $OUTPUT_FILE
# 采集100次,每次间隔5秒
for i in $(seq 1 100); do
TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')
CPU_IDLE=$(top -bn1 | grep "Cpu(s)" | awk '{print $8}' | cut -d'.' -f1)
CPU_USED=$((100 - CPU_IDLE))
MEM_USED=$(free -m | awk 'NR==2{printf "%.1f", $3*100/$2}')
LOAD=$(cat /proc/loadavg | awk '{print $1","$2","$3}')
echo "$TIMESTAMP,$CPU_USED,$MEM_USED,$LOAD" >> $OUTPUT_FILE
sleep 5
done
echo "数据已保存到 $OUTPUT_FILE"
2.8 性能指标解读
2.8.1 CPU指标
| 指标 | 正常范围 | 异常表现 | 可能原因 |
|---|---|---|---|
| us | <70% | >80% | 应用程序消耗CPU |
| sy | <30% | >50% | 系统调用频繁 |
| wa | <20% | >50% | IO瓶颈 |
| st | <5% | >20% | 虚拟化资源争抢 |
2.8.2 内存指标
| 指标 | 正常范围 | 异常表现 | 可能原因 |
|---|---|---|---|
| 使用率 | <80% | >90% | 内存不足 |
| Swap使用 | 0 | 持续增长 | 内存泄漏 |
| buff/cache | 占比高 | 不断下降 | 缓存不足 |
2.8.3 负载指标
| 场景 | 负载值 | CPU核心数 | 判断 |
|---|---|---|---|
| 正常 | 0.5 | 4 | 12.5%,空闲 |
| 中等 | 2.0 | 4 | 50%,正常 |
| 高负载 | 4.0 | 4 | 100%,满载 |
| 过载 | 8.0 | 4 | 等待队列长 |
2.9 常见问题
Q1: top显示的内存使用率很高,但系统正常?
原因: Linux会将空闲内存用作缓存(buff/cache)
解决: 关注 avail Mem 字段,它是实际可用内存
# 查看真实可用内存
free -h
# 或
top # 看第四行的avail Mem
Q2: 如何找出内存泄漏的进程?
方法:
# 1. 按内存排序(按M)
# 2. 观察RES列是否持续增长
# 3. 使用脚本记录
while true; do
top -bn1 | head -20 >> /tmp/mem_monitor.log
sleep 60
done
Q3: 进程状态D是什么意思?
D状态: Disk Sleep,不可中断睡眠
含义: 进程正在等待IO操作,不能被信号中断
常见场景:
- 磁盘IO瓶颈
- NFS挂载问题
- 内核bug
排查:
# 查看D状态进程
ps aux | awk '$8=="D"'
# 查看IO情况
iostat -x 1
# 查看哪个进程在等待IO
iotop
Q4: 多核CPU使用率超过100%?
原因: top默认显示所有CPU核心的总和
解决:
# 按1查看每个核心
top
# 按1
# 或查看进程的单核使用
top -H -p <PID>
2.10 top vs htop 对比
| 特性 | top | htop |
|---|---|---|
| 界面 | 文本单色 | 彩色图形 |
| 鼠标支持 | 否 | 是 |
| 树状视图 | 有限 | 完整 |
| 横向滚动 | 否 | 是 |
| 杀进程 | 输入PID | 直接选择 |
| 配置保存 | 复杂 | 简单 |
| 资源占用 | 更低 | 稍高 |
| 安装 | 系统自带 | 需安装 |
选择建议:
- 临时查看 →
top - 日常管理 →
htop - 无网络环境 →
top
2.11 实战案例
案例1:服务器响应慢
# 1. 检查负载
uptime
# load average: 8.52, 7.58, 6.59 # 4核CPU过载
# 2. 找出CPU消耗高的进程
top -o %CPU
# 发现java进程占用800% CPU
# 3. 分析该进程
top -H -p $(pgrep java)
# 发现多个线程都在高CPU
# 4. 结论:Java应用代码问题
# 联系开发人员排查
案例2:内存不足告警
# 1. 检查内存
free -h
# total used free shared buff/cache available
# Mem: 16G 15G 500M 256M 500M 500M
# Swap: 8G 2G 6G
# 2. 找出内存大户
top -o %MEM
# 发现mysqld占用8G内存
# 3. 检查MySQL配置
grep innodb_buffer_pool_size /etc/mysql/my.cnf
# innodb_buffer_pool_size = 12G # 配置过大
# 4. 解决:调整MySQL配置
# innodb_buffer_pool_size = 8G
案例3:僵尸进程堆积
# 1. 检查僵尸进程
top
# Tasks: 215 total, 2 running, 193 sleeping, 0 stopped, 20 zombie
# 2. 找出僵尸进程
ps aux | grep 'Z'
# 3. 找出父进程
ps -eo pid,ppid,stat,cmd | grep 'Z'
# 发现父进程是某个服务
# 4. 重启父进程
systemctl restart service_name
2.12 快捷命令参考
# 常用启动命令
top # 标准启动
top -c # 显示完整命令
top -H # 显示线程
top -d 5 # 5秒刷新
top -p 1234 # 监控特定PID
top -u mysql # 监控特定用户
top -bn1 # 批处理模式
top -bn1 -o %CPU | head # CPU占用最高的进程
# 常用交互键
P # 按CPU排序
M # 按内存排序
N # 按PID排序
T # 按时间排序
1 # 显示每个CPU核心
c # 显示完整命令
H # 显示线程
V # 树状视图
i # 只显示活跃进程
k # 杀死进程
r # 修改优先级
q # 退出
2.13 扩展阅读
2.14 本章小结
本章详细介绍了top命令的使用:
- 界面解读: 系统概况、CPU、内存、进程列表
- 交互命令: 排序、过滤、进程管理
- 高级用法: 多窗口、树状视图、配置文件
- 脚本化: 批处理模式、监控脚本
- 实战案例: CPU、内存、僵尸进程问题排查
下一章我们将学习 htop,它提供了更友好的交互界面。
上一章: 第1章:监控工具概览 下一章: 第3章:htop详解