判断内存问题需综合available、swap使用率及si/so值:available剩15%以上而Swap used达90%多因swappiness过高;用smaps精确查进程swap占用;si/so持续>10KB/s且iowait飙升才表明内存不足引发I/O雪崩。

看 swap 用了多少,但别只看数字
Swap 使用率高 ≠ 系统出问题。关键要看 available 内存是否真的告急,以及 swap 是否在“频繁进出”。执行 free -h 后,重点盯三列:available(真正可用内存)、Swap used(已用 swap)、buff/cache(可回收缓存)。如果 available 还剩 15% 以上,而 Swap used 却飙到 90%,大概率是 swappiness 设置过高或内核过度激进换出页,而非物理内存真不够。
查谁在偷偷吃内存:不只是 top 那么简单
top 按 M 排序能快速揪出高 %MEM 进程,但容易漏掉两类“隐形大户”:一是大量 fork 子进程却不释放的守护进程(比如旧版 rsyslog 或自研日志 agent),二是容器内进程——宿主机上 ps aux 看不到它真实 RSS,得去 /proc/[pid]/smaps 手动算。推荐这条命令一次性扫全系统各进程 swap 占用:
for i in /proc/[0-9]*; do awk '/^Swap:/ {swap+=$2} END {if(swap>0) print "'$i'", swap/1024 "MB"}' "$i"/smaps 2>/dev/null; done | sort -k2nr | head -10它比 ps 更准,因为直接读取每个进程实际被 swap 出去的物理页数。
盯住 vmstat 的 si/so,判断是不是“假忙”
vmstat 1 5 输出里,si(swap-in)和 so(swap-out)持续非零才说明真在抖动。如果 so 高但 si 极低,可能是某进程刚被换出、还没被访问,暂时无害;但如果 si 和 so 都稳定在 >10(单位 KB/s),说明系统正反复搬运内存页,I/O 压力已传导到磁盘,响应延迟必然升高。此时再看 iowait 是否同步飙升——如果是,基本锁定为内存不足引发的连锁 I/O 雪崩。
别忘了 tmpfs 和内核 slab 这两个“影子内存”
/dev/shm 或 /run 下挂载的 tmpfs 是内存文件系统,它的用量会计入 MemUsed,但不会触发 swap,却会让 free 显示“内存快爆了”。执行 df -hT | grep tmpfs 查用量,再用 du -sh /dev/shm/* 2>/dev/null 看具体谁占大头。另一个易忽略点是内核 slab 分配器:运行 cat /proc/meminfo | grep -i "slab\|sreclaimable",若 SReclaimable 很小但 Slab 总量巨大,可能有内核模块泄漏,需结合 slabtop 进一步定位。
真正麻烦的 case 往往不是 swap 用了多少,而是它被什么触发、是否可逆、会不会在半夜流量高峰时突然恶化。一次 swap 暴涨背后,可能是某个 Python 脚本没关文件句柄导致 page cache 锁死,也可能是 Docker 宿主机对 cgroup memory limit 判定失准——这些细节,free 和 top 都不告诉你。









