glmapper

Linux Top 命令指南

字数统计: 5k阅读时长: 20 min
2020/08/10 Share

top 命令允许用户监视 Linux 上的进程和系统资源使用情况,它是系统管理员工具箱中最有用的工具之一,并且在每个发行版中都预装了它。与 ps 等其他命令不同,它是交互式的,我们可以浏览进程列表、终止进程,等等。本文中,我们将了解如何使用 top 命令。

Getting started

top 命令非常简单,只需要在终端中输入 top 即可。top 指令将启动一个交互式命令行应用程序,如下所示,输出的上半部分包含有关进程和资源使用情况的统计信息,下半部分包含当前运行的进程的列表。可以使用箭头键和页面向上/向下键浏览列表。如果你想退出,只需按q键。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
$ top
top - 21:07:28 up 21 days, 4:31, 1 user, load average: 0.12, 0.06, 0.07
Tasks: 33 total, 1 running, 31 sleeping, 0 stopped, 1 zombie
%Cpu(s): 0.2 us, 0.5 sy, 0.0 ni, 89.7 id, 0.0 wa, 0.0 hi, 0.0 si, 9.6 st
KiB Mem : 33554432 total, 31188884 free, 513100 used, 1852448 buff/cache
KiB Swap: 2097148 total, 2097148 free, 0 used. 31188884 avail Mem

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
52601 root 39 19 1310268 14900 9836 S 0.3 0.0 22:59.21 logagent-collec
1 root 20 0 45416 5244 3968 S 0.0 0.0 5:35.71 systemd
340 root 20 0 64700 21336 17684 S 0.0 0.1 8:33.90 systemd-journal
357 root 20 0 101836 2768 2312 S 0.0 0.0 0:01.13 gssproxy
384 dbus 20 0 28632 2800 2464 S 0.0 0.0 0:00.04 dbus-daemon
432 root 20 0 84760 5852 4984 S 0.0 0.0 0:00.01 sshd
461 agent 20 0 52376 5200 3684 S 0.0 0.0 0:00.01 ilogtail
1690 agent 20 0 2193388 246304 11264 S 0.0 0.7 23:45.88 java
2527 admin 20 0 161744 4268 3704 R 0.0 0.0 0:00.72 top
3245 root 20 0 559140 12412 5860 S 0.0 0.0 64:48.67 logagent
3420 root 20 0 745052 58464 43820 S 0.0 0.2 11:16.32 metricbeat
3447 root 20 0 957796 55548 43708 S 0.0 0.2 10:14.47 metricbeat
5093 root 20 0 1905356 159280 9584 S 0.0 0.5 35:00.14 java
7458 root 20 0 13700 2564 2356 S 0.0 0.0 0:00.00 bash
7464 root 20 0 86268 4436 3740 S 0.0 0.0 0:00.00 sudo
# ... 省略其他

top 有许多变体,但在本文的其余部分中,我们将讨论最常见的变体 — props -ng包附带的变体,下面来运行验证体验下:

1
2
3
4
$ top -v
procps-ng version 3.3.10
Usage:
top -hv | -bcHiOSs -d secs -n max -u|U user -p pid(s) -o field -w [cols]

top 的界面中发生了相当多的事情,我们将在下一节中对其逐一进行分析。

了解 top 的界面 - the summary area

第一小节中 top 的输出界面,我们可以比较明显的看到被分成了两个部分,这个小节中我们将关注在上半部分信息,这部分一般被称之为:summary area

系统时间、正常运行时间和用户会话

  • 系统时间:当前系统的时间(21:07:28)
  • 正常运行:系统运行时长(21 days, 4:31)
  • 活动用户会话个数:1 个
1
top - 21:07:28 up 21 days,  4:31,  1 user,

活动用户会话包括 TTYPTY 两种。实际上,如果您通过桌面环境登录到 Linux 系统,然后启动终端模拟器,您将发现将有两个活动会话。

TTY: 通过命令行或桌面环境在系统上物理地运行
PTY: 终端模拟器窗口或通过 SSH

如果我们期望得到更多关于活动用户会话的信息,可以通过 who 命令来得到,如下:

1
2
$ who
admin pts/0 2020-10-31 17:15 (xx.xx.xx.xx)

内存使用情况

Memory 部分显示的是关于系统内存使用情况的信息,如下:

1
2
KiB Mem : 33554432 total, 31188208 free,   513488 used,  1852736 buff/cache
KiB Swap: 2097148 total, 2097148 free, 0 used. 31188208 avail Mem

MemSwap 分别显示的是 RAMswap 空间信息;当 RAM 使用率接近满时,RAM 中不经常使用的区域将被写入 Swap 空间,以便稍后需要时检索。但是,由于访问磁盘的速度很慢,过分依赖 Swap 可能会损害系统性能。

关于 Swap

  • 物理内存就是计算机的实际内存大小,由RAM芯片组成的。虚拟内存则是虚拟出来的、使用磁盘代替内存。虚拟内存的出现,让机器内存不够的情况得到部分解决。当程序运行起来由操作系统做具体虚拟内存到物理内存的替换和加载(相应的页与段的虚拟内存管理)。这里的虚拟内存即所谓的 swap;

  • 当用户提交程序,然后产生进程,在机器上运行。机器会判断当前物理内存是否还有空闲允许进程调入内存运行,如果有那么则直接调入内存进行运行;如果没有,那么会根据优先级选择一个进程挂起,把该进程交换到swap中等待,然后把新的进程调入到内存中运行。根据这种换入和换出,实现了内存的循环利用,让用户感觉不到内存的限制。从这也可以看出swap扮演了一个非常重要的角色,就是暂存被换出的进程。

  • 内存与swap之间是按照内存页为单位来交换数据的,一般Linux中页的大小设置为4kb。而内存与磁盘则是按照块来交换数据的

totalfreeused 就是这些单词含义所描述的一样,分别是当前对应空间的总大小、空闲大小、已使用大小。avail mem 值指的是可以分配给进程而不会导致更多的交换的内存量。

Linux 内核层面上总是以不同的方式来尝试减少访问磁盘的次数;它在RAM中维护一个“磁盘缓存(disk cache)”,存储磁盘中经常使用的区域,另外,磁盘写被存储到一个“磁盘缓冲区(disk buffer)”,内核最终将它们写到磁盘上。它们消耗的总内存是 buff/cache 值。这看起来像是一件坏事,但实际上不是,原因是缓存使用的内存将在需要时分配给进程。

任务-Tasks

Tasks 部分显示的是有关系统上运行的进程的统计信息

1
Tasks:  33 total,   1 running,  31 sleeping,   0 stopped,   1 zombie

total 比较好理解,它表示的就是当前系统正在运行的进程总数。但是对于其他几个状态相关的数字,我们需要了解一点 Linux 内核如何处理进程的背景知识。

进程执行是 I/O 限制的工作(如读取磁盘)和 cpu 限制的工作(如执行算术操作)的混合模式。当一个进程执行 I/O 时,CPU 是空闲的,所以 os 在这段时间切换到执行其他进程。此外,该操作系统允许一个给定的进程执行非常短的时间,然后它切换到另一个进程。这就是操作系统“多任务处理”的表现。做所有这些需要我们跟踪流程的“状态”。在 Linux 中,进程可能处于以下状态:

  • 1、Runnable (R): 处于这种状态的进程要么在 CPU 上执行,要么存在于运行队列中,准备执行。
  • 2、Interruptible sleep(S): 处于这种状态的进程在等待事件完成。
  • 3、Uninterruptible sleep (D): 在这种情况下,一个进程正在等待一个 I/O 操作完成。
  • 4、Stopped (T): 这些进程已经被一个作业控制信号(如按 Ctrl+Z)停止,或者因为它们正在被跟踪。
  • 5、Zombie (Z): 僵尸进程

一个进程可以创建许多子进程,当父进程仍然存在时,这些子进程是可以退出的,但是,这些数据结构必须保留下来,直到父进程获得子进程的状态。这种数据结构仍然存在的终止进程称为僵尸进程。D 和 S 状态都是在 top 信息中体现为 sleeping,T 状态体现为 stoppedZ 状态体现为 zombie

CPU 使用情况

CPU 使用情况,显示了在各种任务上花费的 CPU 时间的百分比。

1
%Cpu(s):  0.3 us,  0.4 sy,  0.0 ni, 90.3 id,  0.0 wa,  0.0 hi,  0.0 si,  9.0 st

us指的是 CPU 在用户空间中执行进程所花费的时间。类似地,sy指的就是运行内核空间进程所花费的时间。Linux 中使用 nice 值来表示进程的优先级,值越高,优先级越低,后面我们会了解到,默认的 nice 值是可以被修改的。在手动设置 nice 的情况下,执行进程所花费的时间显示为 ni 值。ni 后面是 id,它是CPU 保持空闲的时间,大多数操作系统在 CPU 空闲时将其设置为“省电模式”。接下来是 wa值,它是 CPU 等待 I/O 完成所花费的时间。

中断(Interrupt)是向处理器发出的有关需要立即关注的事件的信号;外设通常使用硬件中断来告知系统有关事件的信息,例如键盘上的按键。另一方面,软件中断是由于处理器上执行的特定指令而产生的。在这两种情况下,操作系统都将处理它们,处理硬件中断和软件中断所花费的时间分别由hisi给出。

在虚拟化环境中,会将一部分 CPU 资源分配给每个虚拟机(VM)。操作系统会检测到何时有工作要做,如果检测到他需要执行但是由于 CPU 在其他 VM 上繁忙而无法执行时,以这种方式浪费的时间就是“窃取”时间,显示为st

平均负载-Load average

load average 部分表示的是在最近 1、5 和 15 分钟内的系统平均“负载”。

1
load average: 0.11, 0.07, 0.07

负载是对系统执行的计算工作量的度量。在Linux上,负载是在任何给定时刻处于 RD 状态的进程数。load average值为您提供了必须等待多长时间才能完成任务的相对度量。这里有几个小例子,我们来直观的理解下这两个概念。

  • 1、在单核心系统上,load average 为 0.4 意味着系统只完成了它能完成的 40% 的工作。load average为 1 意味着系统正好处于满负荷状态——即使添加一点点额外的工作,系统也会过载。一个 load average 为 2.12 的系统意味着它超载了 112% 的工作,超出了它的处理能力。
  • 2、在多核系统上,应该首先用 load average 除以 CPU 核数,以得到类似的度量。

此外,load average 实际上并不是我们大多数人所知道的典型的平均负载。它是一个“指数移动平均”,这意味着以前的 load average 的一小部分被考虑到当前的值(关于这个点,可以通过这篇文章来了解更多技术细节)。

了解 top 的界面 - the task area

summury area 相对简单,通过它我们可以快速了解到当前系统运行的一些摘要统计信息。但是一个细节性的信息,我们只能通过 task area 中来得到。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
52601 root 39 19 1310268 14900 9836 S 0.3 0.0 22:59.21 logagent-collec
1 root 20 0 45416 5244 3968 S 0.0 0.0 5:35.71 systemd
340 root 20 0 64700 21336 17684 S 0.0 0.1 8:33.90 systemd-journal
357 root 20 0 101836 2768 2312 S 0.0 0.0 0:01.13 gssproxy
384 dbus 20 0 28632 2800 2464 S 0.0 0.0 0:00.04 dbus-daemon
432 root 20 0 84760 5852 4984 S 0.0 0.0 0:00.01 sshd
461 agent 20 0 52376 5200 3684 S 0.0 0.0 0:00.01 ilogtail
1690 agent 20 0 2193388 246304 11264 S 0.0 0.7 23:45.88 java
2527 admin 20 0 161744 4268 3704 R 0.0 0.0 0:00.72 top
3245 root 20 0 559140 12412 5860 S 0.0 0.0 64:48.67 logagent
3420 root 20 0 745052 58464 43820 S 0.0 0.2 11:16.32 metricbeat
3447 root 20 0 957796 55548 43708 S 0.0 0.2 10:14.47 metricbeat
5093 root 20 0 1905356 159280 9584 S 0.0 0.5 35:00.14 java
7458 root 20 0 13700 2564 2356 S 0.0 0.0 0:00.00 bash
7464 root 20 0 86268 4436 3740 S 0.0 0.0 0:00.00 sudo

先来说明下各个列的含义:

PID

这是进程ID,一个惟一的正整数,用于标识进程。

USER

这是启动进程的用户的“有效”用户名(映射到用户ID)。Linux 为进程分配一个真实的用户 ID 和一个有效的用户ID;后者允许进程代表另一个用户进行操作。(例如,非 root 用户可以提升到 root 用户来安装软件)

PR NI
“NI” 字段显示进程的 “nice” 值,“PR” 字段是从内核的角度显示了进程的调度优先级,“nice” 值影响的是进程的优先级。

VIRT, RES, SHR and %MEM

VIRTRESSHR 这三个字段都与进程的内存消耗有关。VIRT是一个进程所消耗的内存总量。这包括程序代码、进程在内存中存储的数据,以及已经 swap 到磁盘的任何内存区域。RES是进程在 RAM 中消耗的内存,%MEM 表示这个值占总可用 RAM 的百分比。最后,SHR 是与其他进程共享的内存量。

S
表示进程状态

TIME+

TIME+ 列表示的是进程自启动以来所使用的总 CPU 时间,精确到百分之一秒。

COMMAND

COMMAND 列表示的是当前进程的名称。

top 命令的使用示例

到目前为止,我们已经讨论了 top 的界面信息所描述的含义。但是,top 除了显示这个信息之外,它还可以管理进程,并且我们可以控制 top 输出的各个方面。在本节中,我们将举几个例子。(在下面的大多数例子中,你必须在 top 运行时按下一个键。这些按键是区分大小写的,所以如果你在大写锁定状态下按了k,你实际上已经按了一个k,但是这个命令并不会工作)

kill 进程

如果你想杀死一个进程,只要在top运行时按k。这将出现一个提示,它将询问进程的进程ID并按enter

1
PID to signal/kill [default pid = 384]

当然上面的这段输出的后面是可以手动输入进程 ID,下面的 34444444444444 就是手动输入的进程ID

1
PID to signal/kill [default pid = 384] 34444444444444

如果保留此空白,top 将使用一个SIGTERM,它允许进程优雅地终止。如果您想强制终止进程,您可以在这里输入SIGKILL。你也可以在这里输入信号号,例如,SIGTERM 的数字是 384,而 SIGKILL 的数字是。如果你将进程ID留空并直接按enter`,它将终止列表中最顶端的进程。正如前面提到的,我们也可以使用箭头键滚动,并通过这种方式更改想要终止的进程。

排序进程列表

使用像 top 这样的工具的一个最常见的原因是找出哪个进程消耗的资源最多。我们可以按以下键排序列表:

  • M:用于按内存使用情况排序
  • P:来按CPU使用率排序
  • N:按进程ID排序
  • T:来按运行时间排序

默认情况下,top 按降序显示所有结果,但是我们可以通过按R键切换到升序。还可以使用 -o 开关对列表进行排序。例如,如果想排序进程的CPU使用量,可以这样做:

1
top -o %CPU

显示线程列表而不是进程列表

前面已经介绍过 Linux 如何在进程之间切换。我们知道,进程是不共享内存或其他资源的,这使得这种切换相当慢。和其他操作系统一样,Linux 支持一种“轻量级”的替代方案,称为“线程”。“线程”是进程的一部分,“线程”可以共享内存和其他资源的某些区域,同时它们也可以像进程一样并发运行。默认情况下,top在其输出中显示一个进程列表。如果想列出线程代替进程,按 H 即可,此时 “Tasks” 行将显示的是 “Threads”,显示的是线程的数量,而不是进程的数量。

1
Threads: 351 total,   2 running, 349 sleeping,   0 stopped,   0 zombie

细心的读者可能会发现, summury area 中的 “Tasks” 行已经改变成 “Threads” 的了,但是在 task area 中,对应的列表中的属性却没有任何更改,那既然进程和线程不同,这怎么可能呢? 原因是在 Linux 内核内部,线程和进程使用相同的数据结构进行处理,因此,每个线程都有自己的ID、状态等等。如果我们要切换回进程视图,则再次按 H 即可。此外,也可以使用 top -H 在默认情况下显示线程。

显示进程完整路径

默认情况下,COMMAND 列下的所有进程名显示的都是摘要名,如果我们期望显示当前进程的完成路径,可以通过按 c 来切换视角,或者直接使用 top -c 来启动交互界面。

以树形结构显示父子进程

可以通过在 top 交互中按 V 来切到 forest view 视角,即以以树形结构显示父子进程。

1
2
3
4
5
   432 root      20   0   84760   5852   4984 S   0.0  0.0   0:00.01  `- /usr/sbin/sshd -D
98518 root 20 0 118432 6884 5792 S 0.0 0.0 0:00.00 `- sshd: admin [priv]
98520 admin 20 0 118432 3648 2556 S 0.0 0.0 0:01.32 `- sshd: admin@pts/0
98521 admin 20 0 120656 4936 3768 S 0.0 0.0 0:00.34 `- -bash
130138 admin 20 0 161748 4208 3624 R 0.0 0.0 0:00.27 `- top -c

列出用户的进程

要列出某个用户的进程,请在top运行时按 u。然后,输入用户名,或者留空以显示所有用户的进程;或者直接通过 top -u xxx 来指定 xxx 用户的所有进程信息。

1
2
3
4
5
6
7
KiB Swap:  2097148 total,  2097148 free,        0 used. 31179088 avail Mem
Which user (blank for all) root # waiting for input
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1 root 20 0 45416 5244 3968 S 0.0 0.0 5:37.57 /usr/lib/systemd/systemd --system --deserialize 18
340 root 20 0 72892 30836 27184 S 0.0 0.1 8:36.56 /usr/lib/systemd/systemd-journald
357 root 20 0 101836 2768 2312 S 0.0 0.0 0:01.14 /usr/sbin/gssproxy -D
432 root 20 0 84760 5852 4984 S 0.0 0.0 0:00.01 /usr/sbin/sshd -D

过滤进程

如果我们需要处理许多进程,那么简单的排序实际上对我们的帮助并不是很大。那么在这种情况下,我们可以按 o 来激活 top 的过滤模式,然后通过输入一个过滤器表达式来过滤到我们的目前进程。过滤器表达式是指定属性和值之间关系的语句,例如:

  • COMMAND=java: 进程名=java 的
  • !COMMAND=java: 进程名 !=java 的
  • %CPU>3.0: CPU > 3.0 的

如果要清除所有过滤条件的话,按 = 即可。

总结

本文主要是对A Guide to the Linux “Top” Command 这篇文章的一些内容翻译,感谢原作者提供的分享

top 命令对于监视和管理 Linux 系统上的进程非常有帮助,本文只是从表面做了一些简单的介绍,还有很多我们没有涉及到的内容;例如,如何在 top 中添加更多的列。更多信息,可以通过运行 man top 查看 man 页面,来进行更深层面的学习。

原文作者:GuoLei Song

原文链接:http://www.glmapper.com/2020/08/10/linux/base-operations-top-command/

发表日期:August 10th 2020, 4:55:06 pm

更新日期:November 1st 2020, 12:20:30 am

版权声明:转载请注明出处

CATALOG
  1. 1. Getting started
  2. 2. 了解 top 的界面 - the summary area
    1. 2.1. 系统时间、正常运行时间和用户会话
    2. 2.2. 内存使用情况
    3. 2.3. 任务-Tasks
    4. 2.4. CPU 使用情况
    5. 2.5. 平均负载-Load average
  3. 3. 了解 top 的界面 - the task area
  4. 4. top 命令的使用示例
    1. 4.1. kill 进程
    2. 4.2. 排序进程列表
    3. 4.3. 显示线程列表而不是进程列表
    4. 4.4. 显示进程完整路径
    5. 4.5. 以树形结构显示父子进程
    6. 4.6. 列出用户的进程
    7. 4.7. 过滤进程
  5. 5. 总结