date: 2020-10-20T09:26:21+08:00 # 创建日期 author: "Rustle Karl" # 作者
title: "top 进程活动监视" # 文章标题
url: "posts/linux/tools/standard/top" # 设置网页永久链接 tags: [ "linux", "cmd" ] # 标签 series: [ "Linux 学习笔记" ] # 系列 categories: [ "学习笔记" ] # 分类
weight: 20 # 排序优先级 chapter: false # 设置为章节
动态地监视进程活动与系统负载等信息
top -hv | -bcHiOSs -d secs -n max -u|U user -p pID(s) -o field -w [cols]| 参数 | 作用 |
|---|---|
| -h | 帮助信息 |
| -v | 版本信息 |
| -b | 以批处理模式操作 |
| -c | 命令行 / 程序名切换 |
| -H | 显示线程运行情况 |
| -i | 空闲进程切换 |
| -S | 累积模式 |
| -s | 保密模式 |
| -I | 忽略失效过程 |
| -d | 显示信息刷新间隔时间 |
-n< 次数 > |
循环显示的次数 |
| -u | U< 用户名 > |
-p< 进程号 > |
仅显示指定进程的信息 |
top
top - 09:12:12 up 18:42, 0 users, load average: 0.03, 0.05, 0.01
Tasks: 83 total, 1 running, 52 sleeping, 0 stopped, 0 zombie
%Cpu(s): 1.1 us, 1.3 sy, 0.0 ni, 97.2 ID, 0.3 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 1009060 total, 68760 free, 328936 used, 611364 buff/cache
KiB Swap: 969964 total, 962272 free, 7692 used. 503076 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1 root 20 0 77528 6144 4156 S 0.0 0.6 0:01.88 systemd
2 root 20 0 0 0 0 S 0.0 0.0 0:00.00 kthreadd
4 root 0 -20 0 0 0 I 0.0 0.0 0:00.00 kworker/0:0H
11 root rt 0 0 0 0 S 0.0 0.0 0:00.15 watchdog/0
14 root 0 -20 0 0 0 I 0.0 0.0 0:00.00 netns
23 root 0 -20 0 0 0 I 0.0 0.0 0:00.00 crypto前 5 行是系统统计信息,其所代表的含义如下:
- 第 1 行:任务队列信息,同
uptime命令执行结果。依次是系统时间、运行时间、登录终端数、系统负载(即任务队列的平均长度。三个数值分别为 1 分钟、5 分钟、15 分钟内的平均值,数值越小意味着负载越低)。一个 CPU 在一个时间片里面只能运行一个进程,CPU 核数的多少直接影响到这台机器在同时间能运行的进程数。所以一般来说 Load Average 的数值别超过这台机器的总核数,就基本没啥问题。 - 第 2 行:进程信息。依次是进程总数、运行中的进程数、睡眠中的进程数、停止的进程数、僵死的进程数。
- 第 3 行:CPU 相关的百分比信息。依次是用户占用资源百分比、系统内核占用资源百分比、改变过优先级的进程资源百分比、空闲(ID/id)的资源百分比、等待输入输出(wa)的百分比等。
- 第 4 行:物理内存总量、物理内存使用量、内存空闲量、作为内核缓存的内存量。
- 第 5 行:交换空间总量、交换空间使用量、交换空间空闲量、已被提前加载的内存量。
统计信息下方显示了各个进程的详细信息,各列的含义如下:
| 代码 | 列名 | 含义 |
|---|---|---|
| a | PID | 进程 ID |
| b | PPID | 父进程 ID |
| c | RUSER | Real User Name |
| d | UID | 进程所有者的用户 ID |
| e | USER | 进程所有者的用户名 |
| f | GROUP | 进程所有者的组名 |
| g | TTY | 启动进程的终端名,不是从终端启动的进程则显示为 ? |
| h | PR | 优先级 |
| i | NI | Nice 值。负值表示高优先级,正值表示低优先级 |
| j | P | 最后使用的 CPU,仅在多 CPU 环境下有意义 |
| k | % CPU | 上次更新到现在的 CPU 时间占用百分比 |
| l | TIME | 进程使用的 CPU 时间总计,单位秒 |
| m | TIME+ | 进程使用的 CPU 时间总计,单位 1/100 秒 |
| n | % MEM | 进程使用的物理内存百分比 |
| o | VIRT | 进程使用的虚拟内存总量,单位 kb。VIRT = SWAP+RES |
| p | SWAP | 进程使用的虚拟内存中,被换出的大小,单位 kb |
| q | RES | 进程使用的、未被换出的物理内存大小,单位 kb。RES = CODE+DATA |
| r | CODE | 可执行代码占用的物理内存大小,单位 kb |
| s | DATA | 可执行代码以外的部分 ( 数据段 + 栈 ) 占用的物理内存大小,单位 kb |
| t | SHR | 共享内存大小,单位 kb |
| u | nFLT | 页面错误次数 |
| v | nDRT | 最后一次写入到现在,被修改过的页面数 |
| w | S | 进程状态 |
| x | COMMAND | 命令名 / 命令行 |
| y | WCHAN | 若该进程在睡眠,则显示睡眠中的系统函数名 |
| z | Flags | 任务标志 linux/sched.h |
- 更新 2 次后终止更新显示
top -n 2- 设置信息更新周期为 3 秒
top -d 3- 仅显示 PID 为 1138 的进程信息
top -p 1138简单说就是:等待磁盘I/O完成的进程过多,导致进程队列长度过大,但是 CPU 运行的进程却很少。
负载就是 cpu 在一段时间内正在处理以及等待 cpu 处理的进程数之和的统计信息。
负载分为两大部分:CPU 负载、IO 负载。
负载表示的是“等待进程的平均数”。除了 running 状态,其他都是等待状态。
事实证明,只有进程处于运行态(running)和不可中断状态(interruptible)才会被加入到负载等待进程中,也就是下面这两种情况的进程才会表现为负载的值。
- 即便需要立即使用 CPU,也还需等待其他进程用完 CPU
- 即便需要继续处理,也必须等待磁盘输入输出完成才能进行
下面描述一种直观感受的场景说明为什么只有运行态(running)和可中断状态(interruptible)才会被加入负载。
在很占用 CPU 资源的处理中,例如在进行动画编码的过程中,虽然想进行其他相同类型的处理,结果系统反映却变得很慢,还有从磁盘读取大量数据时,系统的反映也同样会变的很慢。但是另一方面,无论有多少等待键盘输入输出操作的进程,也不会让系统响应变慢。
- 等待被授权予 CPU 运行权限的进程
- 等待磁盘 I/O 完成的进程
cpu 低而负载高也就是说等待磁盘 I/O 完成的进程过多,就会导致队列长度过大,这样就体现到负载过大了,但实际是此时 cpu 被分配去执行别的任务或空闲,具体场景有如下几种。
上面说过,cpu 的工作效率要高于磁盘,而进程在 cpu 上面运行需要访问磁盘文件,这个时候 cpu 会向内核发起调用文件的请求,让内核去磁盘取文件,这个时候会切换到其他进程或者空闲,这个任务就会转换为不可中断睡眠状态。当这种读写请求过多就会导致不可中断睡眠状态的进程过多,从而导致负载高,cpu 低的情况。
我们都知道 MySQL 的数据是存储在硬盘中,如果需要进行 sql 查询,需要先把数据从磁盘加载到内存中。当在数据特别大的时候,如果执行的 sql 语句没有索引,就会造成扫描表的行数过大导致 I/O 阻塞,或者是语句中存在死锁,也会造成 I/O 阻塞,从而导致不可中断睡眠进程过多,导致负载过大。
具体解决方法可以在 MySQL 中运行 show full processlist 命令查看线程等待情况,把其中的语句拿出来进行优化。
比如我们的系统挂载了外接硬盘如 NFS 共享存储,经常会有大量的读写请求去访问 NFS 存储的文件,如果这个时候 NFS Server 故障,那么就会导致进程读写请求一直获取不到资源,从而进程一直是不可中断状态,造成负载很高。