内存 90% 不一定是故障:Linux 内存账怎么读才准
看到 free 只剩几百兆就紧张,是很多人的条件反射。但 Linux 会把空闲内存拿去做 page cache,free 小是正常的——关键看 available。
真正危险的是 available 持续走低,加上 swap 频繁换入换出,最终触发 OOM killer 杀进程。
先说结论
看 available,不看 free;看 swap 换入换出,不看 swap 用了多少。 available 才是「还能给新进程用多少」。
- free -h 的 available 列是判断依据
- vmstat 1 看 si/so(换入换出)是否非零
- slabtop 看内核对象占用
- dmesg -T | grep -i oom 查被杀记录
先把问题说清楚
page cache 属于「可回收」,所以 free 小不代表没内存。真正不可回收的是内核 slab、共享内存、以及匿名页。
容器场景还要看 cgroup 限制:docker stats 显示的是容器视角,宿主机可能还很宽裕。
具体怎么做
按顺序执行,每步都验证完再进下一步:
- free -h 看 available;连续观察 5 分钟趋势
- vmstat 1 5 看 si/so,长期非零说明已经在换页
- ps aux --sort=-rss | head 找 RSS 大户,注意 RSS 会重复计算共享库
- slabtop -o | head 看内核缓存是否异常增长(常见于 inode/dentry)
- dmesg -T | grep -i -E 'oom|killed process' 确认是否发生过 OOM
参数与成本对照
把关键数值摊开,方便判断该选哪条路:
| 字段 | 含义 | 该怎么读 |
|---|---|---|
| free | 完全未使用的内存 | 小是正常的,被 cache 占了 |
| available | 可分配给新进程的估算值 | 真正的判断依据 |
| buff/cache | page cache + slab | 大部分可回收 |
| si/so | swap 换入/换出速率 | 长期非零=内存压力大 |

几个容易踩的坑
下面这些是最常见的错误做法:
- 看到 free 小就重启服务:缓存清空后反而更慢
- 用 echo 3 > drop_caches 当常规操作:会拖慢整个系统
- 只盯容器内数字,忽略宿主机
- 把 Java 的 -Xmx 设得比容器 limit 还大,必然被 OOM
最后补两句
内存问题的判断标准只有一条:available 够不够,以及系统是否在换页。其余数字都是参考。
工具是手段,理解机制才是能力。命令记不住没关系,知道「该看什么」就够了。
评论 (3)
照着做了一遍,确实少走弯路。第二步最容易漏,建议顺手加个检查清单。
比「一键脚本」有用多了,知道为什么比知道怎么做重要。
补充一句:不同版本行为会变,动手前先确认自己的版本号。
发表评论