如何在 Linux 上使用 vmstat 命令

你的 Linux 或 macOS 电脑正在使用虚拟内存。理解它是如何影响你的系统对物理内存、CPU 和硬盘资源的使用至关重要。

什么是虚拟内存?

你的计算机配备了有限的物理内存,通常被称为随机存取存储器 (RAM)。 这部分 RAM 由内核进行管理,并在操作系统和所有运行的应用之间共享。 当这些所有需求加起来需要的内存超过了你计算机实际安装的内存时,内核该怎么办?

包括 macOS 在内的 Linux 和类 Unix 操作系统,可以使用硬盘空间来辅助管理内存需求。 可以使用硬盘上一个名为“交换空间”的特定区域,将其视为 RAM 的延伸。 这就是虚拟内存的运作方式。

Linux 内核可以将一部分内存的内容写入交换空间,从而释放这部分 RAM 供其他进程使用。被换出(也称“分页”)的内存可以在需要时从交换空间中读取并恢复到 RAM 中。

当然,从硬盘读取分页内存的速度肯定比从 RAM 读取要慢。 这并不是唯一的代价。 虽然虚拟内存为 Linux 提供了一种管理内存需求的方法,但使用虚拟内存也会给计算机的其他部分带来额外负担。

你的硬盘需要执行更多的读写操作。内核,因此也包括 CPU,必须做更多的工作,因为它要不断地换出内存、换入内存,并保持一切运转以满足不同进程的内存需求。

Linux 通过 vmstat 命令为你提供了一种监视所有这些活动的方式,此命令会报告虚拟内存统计

vmstat 命令

如果你直接输入 vmstat 而不带任何参数,它会显示一系列数值。 这些数值是自你的计算机上次重启以来各项统计数据的平均值。这些数字并不是“当前”的瞬时值。

vmstat

这将显示一个简短的数值表格。

表格中有 Procs、Memory、Swap、IO、System 和 CPU 这几列。 最右边一列包含与 CPU 相关的数据。

以下是每列中数据项的列表:

进程

r:可运行进程的数量。 这些是已经启动并正在运行,或者正在等待下一个 CPU 时间片的进程。

b:处于不间断睡眠状态的进程数。进程并非真的在休眠,而是正在执行阻塞的系统调用,在完成当前操作之前不能被中断。 通常,这种进程是在等待某些资源被释放的设备驱动程序。 当进程恢复正常活动时,会处理任何排队的中断。

内存

swpd:正在使用的虚拟内存量。换句话说,有多少内存被换出。

free:空闲(当前未使用)的内存量。

buff:用作缓冲区的内存量。

cache:用作缓存的内存量。

交换

si:从交换空间换入的虚拟内存量。

so:换出到交换空间的虚拟内存量。

IO

bi:从块设备接收到的数据块。用于将虚拟内存换回 RAM 的数据块数量。

bo:发送到块设备的数据块。 用于将虚拟内存从 RAM 换出到交换空间的数据块数量。

系统

in:每秒中断的次数,包括时钟。

cs:每秒上下文切换的次数。 上下文切换是指内核从系统模式处理切换到用户模式处理的时候。

CPU

这些值都表示总 CPU 时间的百分比。

us:运行非内核代码所花费的时间。也就是说,用户时间处理和漂亮时间处理所花费的时间。

sy:运行内核代码所花费的时间。

id:空闲时间。

wa:等待输入或输出所花费的时间。

st:从虚拟机中窃取的时间。这是虚拟机必须等待管理程序服务完其他虚拟机后,才能返回并处理自身的时间。

使用时间间隔

我们可以通过使用延迟值来让 vmstat 定期更新这些数值。延迟值以秒为单位。 要每五秒更新一次统计信息,我们将使用以下命令:

vmstat 5

每五秒,vmstat 会向表中添加新的一行数据。 你需要按 Ctrl+C 来停止此操作。

使用计数值

使用过低的延迟值可能会给你的系统带来额外的压力。 如果你需要快速更新以尝试诊断问题,建议你使用计数值和延迟值。

count 值告诉 vmstat 在退出并返回命令提示符之前要执行多少次更新。 如果没有提供计数值,vmstat 将会一直运行,直到你按下 Ctrl+C 停止它。

要让 vmstat 每五秒提供一次更新(但仅更新四次),可以使用以下命令:

vmstat 5 4

四次更新后,vmstat 会自动停止。

更改单位

你可以使用 -S(单位字符)选项来选择以千字节或兆字节显示内存和交换统计信息。 后面必须跟随 kKmM 中的一个。这些分别表示:

k 1000字节
K 1024字节
m 1000000字节
M 1048576 字节

要以 MB 为单位显示内存和交换统计信息并每 10 秒更新一次统计信息,可以使用以下命令:

vmstat 10 -S M

内存和交换统计信息现在以兆字节显示。 请注意,-S 选项不会影响 IO 块统计信息。这些总是以块的形式显示。

活动和非活动内存

如果你使用 -a (active) 选项,buffcache 内存列将被替换为 inactactive 列。 正如其名称所示,这些列显示了非活动和活动内存的数量。

要查看这两列而不是 buffcache 列,请包含 -a 选项,如下所示:

vmstat 5 -a -S M

非活动列和活动列会受 -S(单位字符)选项的影响。

分支

-f 开关显示自计算机启动以来发生的分支数量。

换句话说,这显示了自系统启动以来启动的任务数量(并且对于大多数任务来说,之后又关闭了)。 从命令行启动的每个进程都会增加这个数字。 每当一个任务或进程产生或克隆一个新任务时,这个数字也会增加。

vmstat -f

分叉的显示不会更新。

显示 Slabinfo

内核有其自己的内存管理需求需要考虑,以及操作系统和所有应用程序的内存管理。

正如你可能想象的那样,内核为了处理许多不同类型的数据对象,必须一次又一次地分配和释放内存。 为了尽可能提高效率,它使用了一个称为 slab 的系统。 这是一种缓存形式。

为特定类型的内核数据对象分配、使用和不再需要的内存可以重新用于相同类型的另一个数据对象,而无需释放和重新分配内存。 可以把 slab 看作是为内核自身需求预先分配、定制的 RAM 段。

要查看 slab 的统计信息,请使用 -m (slabs) 选项。 你需要使用 sudo,系统会提示你输入密码。 由于输出可能很长,我们将它通过管道传递给 less

sudo vmstat -m | less

输出包含五列。 它们是:

cache:缓存的名称。

num:此缓存中当前活动对象的数量。

total:此缓存中可用对象的总数。

size:缓存中每个对象的大小。

pages:当前(至少)一个对象与此缓存关联的内存页总数。

q 退出 less

显示事件计数器和内存统计信息

要显示事件计数器和内存统计信息页面,请使用 -s(统计信息)选项。 请注意,这是一个小写的 s

vmstat -s

尽管报告的统计信息与构成默认 vmstat 输出的信息基本相同,但其中一些被更详细地拆分出来了。

例如,默认输出会将 nice 和 non-nice 用户 CPU 时间合并到 us 列中。 -s (stats) 则会单独列出这些统计信息。

显示磁盘统计信息

你可以使用 -d(磁盘)选项来获取类似的磁盘统计信息列表。

vmstat -d | less

对于每个磁盘,会显示三列,分别是 ReadsWritesIO

IO 是最右边的一列。请注意,IO 中的 sec 列以秒为单位,但 readwrite 列中基于时间的统计信息以毫秒为单位。

以下是这些列的含义:

读取

total:磁盘读取的总次数。

merged:分组读取的总次数。

sectors:已读取的扇区总数。

ms:用于从磁盘读取数据的总时间(以毫秒为单位)。

写入

total:磁盘写入的总次数。

merged:分组写入的总次数。

sectors:已写入的扇区总数。

ms:用于将数据写入磁盘的总时间(以毫秒为单位)。

IO

cur:当前正在进行的磁盘读取或写入的次数。

sec:任何正在进行的读取或写入所花费的时间(以秒为单位)。

显示摘要磁盘统计信息

要快速查看磁盘活动的摘要统计信息,请使用 -D(磁盘总和)选项。 注意大写的 D

vmstat -D

磁盘的数量可能看起来异常地多。 用于撰写本文的计算机运行的是 Ubuntu 系统。 在 Ubuntu 中,每次通过 Snap 安装应用程序时,都会创建一个 squashfs 伪文件系统,该文件系统会连接到 /dev/loop 设备。

不幸的是,这些设备条目被许多 Linux 命令和实用工具视为硬盘设备。

显示分区统计信息

要查看与特定分区相关的统计信息,请使用 -p (partition) 选项,并将分区标识符作为命令行参数提供。

在这里,我们将查看分区 sda1。 数字 1 表示这是设备 sda 上的第一个分区,而 sda 是这台计算机的主硬盘。

vmstat -p sda1

返回的信息显示了该分区的磁盘读取和磁盘写入的总次数,以及磁盘读取和磁盘写入操作中所包含的扇区数。

揭开面纱

了解如何揭开计算机的“面纱”并查看其内部运行情况总是好的。 有时你可能在尝试解决问题,有时你只是对计算机的运行方式感到好奇。

vmstat 可以为你提供大量有用的信息。 现在你已经了解了如何访问这些信息以及它们的含义。 做好事先准备总是有益的——当你确实需要动手进行一些诊断时,你会知道 vmstat 就在你身边。