Linux vmstat 的 si 和 so 怎么判断交换抖动
我第一次在生产机上看到 swpd 很大时,直觉是“机器正在疯狂换页”。后来连续看了几十秒才发现,si 和 so 一直是 0:那只是一些冷页仍留在交换区,并不等于系统正在抖动。真正值得警惕的是交换流量持续发生,尤其是页面刚换出又很快被换回,同时业务延迟、任务阻塞或内存压力也在上升。
官方资料:https://man7.org/linux/man-pages/man8/vmstat.8.html、https://docs.kernel.org/accounting/psi.html
判断交换抖动没有一个适用于所有机器的固定 si/so 阈值。先用vmstat -y -w -t 1 60连续采样:如果si、so在多个采样周期反复或同时非零,并伴随b、wa、memory PSI 或业务延迟上升,就应按交换抖动排查;只有swpd非零而 si/so 长期为 0,通常不是抖动。
先分清 swpd、si 和 so 各自回答什么
vmstat 的这三个字段很容易被混在一起。swpd 是当前已经占用的交换空间,是一个存量;si 是每秒从交换设备读回内存的量,so 是每秒从内存写到交换设备的量,它们是采样周期内的流量。si、so 的显示单位受 -S 选项影响,因此跨机器比较前要先确认单位。
这也解释了一个常见现象:系统以前有过内存压力,部分长期不用的匿名页被换出,后来压力已经消失,但这些冷页没有被访问,于是 swpd 仍不为 0,si、so 却保持为 0。此时为了把 swpd 清零而直接执行 swapoff,可能反而制造新的内存风险。

用 60 秒采样避开第一行平均值
我现在排查时会先保留一分钟原始观察窗口,而不是截取单行。vmstat 手册明确说明:第一份报告是从上次开机到现在的平均值,后续报告才对应指定的采样间隔。使用 procps-ng 的 -y 可以直接省略第一份报告,-w 避免大数值挤乱列宽,-t 便于把波动与业务事件对齐。
# 每秒采样一次,共观察 60 个有效周期 vmstat -y -w -t 1 60
检查时先盯住 si 和 so 的连续性,再看同一行的 b 与 wa。单个采样点非零只能说明那个瞬间发生了换页,不能独立证明抖动。若系统里的 vmstat 不支持 -y,可以运行普通的 vmstat 1 61,人工忽略第一份数据,不要把开机以来的平均值与一秒采样混在一起。
按四种形态判断交换压力
| 观察形态 | 更可能的含义 | 判断 |
|---|---|---|
swpd > 0,si/so 长时间为 0 | 冷页留在交换区,当前没有明显交换流量 | 通常不是抖动 |
| si 或 so 偶尔出现一次,随后归零 | 进程启动、恢复访问冷页或短时内存峰值 | 继续观察,不凭单点下结论 |
| so 连续非零,si 很少,内存压力上升 | 内核正在持续回收匿名页,工作集可能逼近物理内存 | 已经有交换压力 |
| si 与 so 在多个周期反复非零,同时 b、wa 或延迟升高 | 活跃工作集在内存与交换设备之间来回搬运 | 高度怀疑交换抖动 |
这里最重要的是“持续”和“影响”。NVMe、SATA SSD、云盘和机械盘承受同样交换速率时,延迟后果可能完全不同;数据库、Java 服务和批处理任务的可接受范围也不一样。因此,与其背一个“si 超过多少就危险”的数字,不如比较同一业务的正常基线,并观察用户请求延迟或吞吐是否同步恶化。
把 b、wa 和可用内存放进同一张判断图
b 表示等待 I/O 完成而阻塞的进程数,wa 表示 CPU 等待 I/O 的时间占比。它们并不专属于交换 I/O,普通磁盘读写同样会推高这些值,所以只能作为相关证据。实际排查时,我会同时打开另一个窗口查看可用内存:
# 查看可用内存与交换区存量 free -h # 查看累计换入、换出页计数 grep -E '^(pswpin|pswpout) ' /proc/vmstat
如果 so 持续出现、可用内存处于低位、pswpout 在观察窗口内不断增长,而 b 或 wa 也同步抬升,交换正在对运行造成影响的证据就更完整。反过来,如果块设备本身繁忙但 si/so 为 0,应转向普通存储 I/O 排查,不要把所有 wa 都归因于 swap。

用 memory PSI 确认任务是否真的被内存拖住
较新的 Linux 环境通常还能读取 /proc/pressure/memory。PSI 的 some 表示至少有部分任务因内存资源受阻,full 表示所有非空闲任务同时受阻;内核文档把持续处于 full 状态的工作负载视为抖动。这个指标比“交换了多少字节”更接近用户实际感受到的停顿。
# 查看最近 10、60、300 秒的内存压力占比 cat /proc/pressure/memory
若文件不存在,说明当前内核或配置没有提供可用的 PSI 接口,继续使用 vmstat、业务延迟和累计页计数即可。若 full avg10 明显上升,并且同一时间 si/so 来回出现,这比单看 swpd 更能支持“系统正在交换抖动”的判断。
确认抖动后先处理工作集,不急着改 swappiness
真正遇到抖动时,我会先找出是谁扩大了活跃工作集,以及最近是否发生了并发、缓存、批处理或容器限额变化:
# 按常驻内存从高到低列出进程,先确认主要使用者 ps -eo pid,comm,rss,vsz --sort=-rss | head -n 15 # 只读取当前 swappiness,先留证据再决定是否调整 sysctl vm.swappiness
短期处置通常是降低并发、暂停可重试批任务、限制缓存增长,或把部分负载迁走;长期处置则是修正内存泄漏、重新估算工作集、调整容器内存上限或增加物理内存。swappiness 描述内核在交换页与文件页回收之间的相对成本偏好,并不是“禁止抖动”的开关。直接把它改成 0,既不能弥补工作集超过内存,也可能把问题推向更剧烈的直接回收或 OOM。
同样,不要在未确认可用内存足够时直接 swapoff -a。该操作需要把仍在交换区的页重新装回内存,压力已经很高时可能让故障进一步扩大。更安全的顺序是先降低工作集,确认 si/so、PSI 和业务延迟回落,再评估是否需要改配置。
常见问题
si 很高但 so 为 0,一定是交换抖动吗?
不一定。应用重新访问之前换出的冷页时,可能出现一段换入而没有同步换出。只有该现象持续、反复,并伴随任务阻塞或业务性能下降,才更接近抖动。
swpd 很大但 si 和 so 都是 0,需要清理吗?
通常不需要仅为了数值好看而清理。它说明有页留在交换区,但当前没有明显搬运。应优先关注可用内存、业务表现和后续采样趋势。
只有 so 持续非零说明什么?
这说明系统正在持续把页换出,已经存在内存回收压力,但不一定已经形成来回换页。继续观察 si 是否随后升高,并结合 PSI、b、wa 和业务延迟判断影响。
vmstat 的 si、so 能直接和两台机器比较吗?
不能只比数字。先统一 -S 单位,再考虑物理内存规模、交换介质速度、采样间隔和工作负载。更可靠的是在同一主机上与正常时段基线比较。
Go template.FuncMap 怎么返回可中断渲染的错误
- 上一篇
- Go template.FuncMap 怎么返回可中断渲染的错误
- 下一篇
- Go SetFinalizer 为什么不能保证进程退出前执行
-
- 文章 · linux | 2小时前 |
- systemd 服务里的 LimitNOFILE 为什么和 shell ulimit 不同
- 258浏览 收藏
-
- 文章 · linux | 6小时前 | Linux Rsync 断点续传 partial-dir
- rsync partial-dir 怎么保留中断的大文件传输
- 294浏览 收藏
-
- 文章 · linux | 1天前 | Linux · 磁盘空间 · 日志清理 journalctl systemd journal vacuum-size vacuum-time
- journalctl 按容量和时间清理归档日志怎么组合
- 321浏览 收藏
-
- 文章 · linux | 1天前 | 定时任务 · Linux · 运维 · Linux OnCalendar Persistent systemd timer
- systemd timer 的 Persistent 为什么能补跑错过任务
- 294浏览 收藏
-
- 文章 · linux | 1天前 | Linux · 故障排查 · Linux GDB coredumpctl systemd-coredump
- coredumpctl 怎么把指定崩溃导出给调试器
- 233浏览 收藏
-
- 文章 · linux | 1天前 | Linux · 运维 · journalctl journald持久化 systemd日志 Storage persistent 重启日志
- journald 怎么把重启前的日志持久化到磁盘
- 166浏览 收藏
-
- 文章 · linux | 1天前 | Linux · 故障排查 · 服务管理 · systemd RestartSec StartLimitBurst StartLimitIntervalSec
- systemd 服务频繁重启时怎么设置启动限流
- 426浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- PubMedQA
- 深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
- 356次使用
-
- H2O EvalGPT
- H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
- 416次使用
-
- LMArena
- LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
- 424次使用
-
- HELM
- 深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
- 380次使用
-
- MMBench
- MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
- 202次使用
-
- Golang Compare And Swap算法详细介绍
- 2022-12-22 345浏览
-
- Go goroutine 泄漏怎么查:pprof、context 和通道关闭检查清单
- 2026-06-27 392浏览
-
- Go select default 为什么会让 CPU 飙高?从空转循环到可控等待
- 2026-07-02 459浏览
-
- Go 服务锁竞争变慢怎么查:mutex profile 的采样、定位和修复手册
- 2026-07-15 395浏览
-
- Go 1.23 以后还要手动 Stop Timer 吗:一次超时循环改造实战
- 2026-07-16 403浏览

