Linux vmstat si/so 长期非零说明什么
来源:17golang原创
时间:2026-09-15 17:20:26 209浏览 收藏
Linux 上看到 vmstat 的 si/so 长期非零,先把它理解成“系统持续在交换空间和内存之间搬运页面”,不要马上等同于内存已经耗尽。si 是从磁盘换入的内存量,so 是换到磁盘的内存量;尤其是 so 在多个采样周期持续增长时,通常说明可回收内存不足,应用工作集正在被挤压。官方字段说明可参考 https://man7.org/linux/man-pages/man8/vmstat.8.html。
- vmstat 第一行是自启动以来的平均值,排查持续换页应使用
vmstat -y 1 10看后续采样行。 - si 非零不一定危险;si 与 so 同时持续、major fault、wa 或 memory PSI 一起升高,才更像实际内存压力。
- 先确认主机内存、swap、容器 cgroup 限额和进程工作集,再考虑调整
vm.swappiness,不要用关闭 swap 掩盖根因。 - 修复后要用相同采样窗口复测,观察 so、
pswpout增量和 PSI 是否同时回落。
先修正时间语义:vmstat 首行不能直接当作当前状态
vmstat 不带延迟参数时输出的是自上次启动以来的平均统计;带上延迟后,第一行仍可能带有启动以来的累计口径,后续行才对应新的采样区间。因此一次看到很大的 si/so,可能只是历史平均或某个短时峰值。
# 跳过启动以来的第一行,只看接下来的 10 个一秒采样区间
vmstat -y 1 10
# 只保留换页、运行队列、阻塞和 I/O 等排查字段
vmstat -y 1 10 | awk 'NR == 1 || NR > 2 { print $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12 }'
关键不是追求某个固定阈值,而是看 so 是否在连续区间都有量、是否伴随 b 或 wa 上升,以及应用延迟是否同步恶化。短时批处理、首次加载大型工作集、休眠页被重新访问,都可能只造成暂时的非零。

si/so 怎样组合才说明内存压力
把两列拆开看更容易误判。si 持续非零,说明之前被换出的页面正在被重新读回,可能是活跃工作集重新访问,也可能只是正常的内存复用;so 持续非零,则表示内核仍在把页面写入 swap。若写出和读回循环出现,应用就可能反复等待慢速存储。
| 观察组合 | 更合理的判断 | 下一步 |
|---|---|---|
| si 偶尔非零,so 接近 0 | 可能是历史换出页被重新访问,未必是持续压力 | 看 major fault、延迟和采样窗口 |
| so 连续非零,free 低且 PSI 上升 | 可用内存不足或受限额挤压 | 查进程 RSS、cgroup memory.current 与限额 |
| si、so 交替升高,wa 也高 | 工作集抖动,换入换出正在影响 I/O 等待 | 降低并发或工作集,确认 swap 设备延迟 |
| si/so 非零但业务无感 | 可能是轻量后台回收或 zram 等快速交换 | 仍需看趋势,不用单点值报警 |
换页量的单位和显示方式受 vmstat 的单位选项影响,所以不要把某个数值跨机器硬套成统一阈值。生产判断应使用同一主机、同一间隔、同一业务时段的趋势。
用 /proc/vmstat、swap 和 PSI 把根因分层
/proc/vmstat 是内核虚拟内存统计的键值文件,pswpin 与 pswpout 是累计计数。连续读取两次并计算差值,可以和 vmstat 的采样区间互相印证;不要把累计值本身当成每秒速率。
# 读取主机的 swap、内存和交换设备,命令只做观察不修改配置
free -h
swapon --show
grep -E '^(Swap|MemAvailable|Active\(|Inactive\()' /proc/meminfo
# 记录两次累计计数,间隔由观察者控制,再用差值判断趋势
grep -E '^(pswpin|pswpout) ' /proc/vmstat
# 检查内存压力停顿;文件不存在时说明当前环境没有暴露 PSI
test -r /proc/pressure/memory && cat /proc/pressure/memory
如果主机 MemAvailable 紧张、pswpout 增长、memory PSI 的 some 或 full 同时升高,优先按内存压力排查。如果只在容器里出现,则进一步查看 cgroup 的 memory.current、memory.max 和 memory.events;宿主机还有空闲内存,并不能证明容器没有触碰自己的上限。

修复顺序:先减少压力,再讨论 swappiness
先找出谁在扩大工作集:检查进程 RSS、缓存增长、批处理并发、tmpfs 使用和容器限额;如果是泄漏或无界缓存,应该修复生命周期或设置上限。如果只是流量峰值,让队列限流、降低并发或错峰通常比立即改内核参数更稳。
vm.swappiness 只能改变内核在回收匿名页和文件页之间的倾向,不能增加物理内存,也不能修复单个进程持续增长。调整前记录现状,变更后用同样的 vmstat -y 1 10、/proc/vmstat 差值和业务延迟复测。不要因为看到 swap 已使用就直接执行 swapoff -a;在内存紧张时强行换回页面,反而可能触发更严重的回收或 OOM。
常见问题
si/so 长期非零是不是一定要加内存?
不一定。先区分短时峰值、zram、容器限额和真实的工作集增长;只有当换页与 PSI、major fault、业务延迟一起持续恶化时,扩容或降低工作集才是直接方向。
为什么 free 看起来还有空间,so 仍然持续?
可能是进程所在 cgroup 的 memory.max 更小,也可能是可用内存而非 free 更接近真实余量。应同时看 MemAvailable、cgroup 事件和进程所在层级。
只看到 si 上升,应该立刻关闭 swap 吗?
不应该。si 只说明页面被读回,先确认是否伴随 so、major fault、I/O 等待和延迟。如果读回是一次性的工作集恢复,关闭 swap 只会减少系统的缓冲空间。
判断 Linux vmstat si/so 的核心,是把“非零”改成“在明确采样区间内持续、并且是否影响了内存压力与业务”。先跳过首行,再把 swap 方向、内核累计计数、PSI 和 cgroup 放到同一时间窗口,最后才决定是修应用、调资源边界还是调整回收策略。
-
345 收藏
-
392 收藏
-
Golang · Go教程 | 2个月前 | channel · select · Context · Go教程 · 性能排查 · select channel context default time.Ticker Go教程 CPU飙高 for select459 收藏
-
395 收藏
-
Golang · Go教程 | 2个月前 | golang · Timer · 并发编程 · time.After · 性能排查 · time.After go timer Go 1.23 NewTimer Timer.Reset Timer.Stop403 收藏
-
206 收藏
-
381 收藏
-
文章 · linux | 4小时前 | cron · 定时任务 · Linux · shell · crontab · Linux cron相对路径失败 cron找不到文件 crontab工作目录 cron环境变量 Linux定时任务排查360 收藏
-
216 收藏
-
436 收藏
-
314 收藏
-
149 收藏
-
324 收藏
-
文章 · linux | 13小时前 | systemd · 日志排查 · journalctl · 运维命令 · Linux教程 · Linux journalctl --since --until --boot 启动编号 Boot ID systemd 日志127 收藏
-
418 收藏
-
215 收藏
-
270 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 485次学习