性能排查 01|free 显示内存用了 90% 就是快满了吗?buff/cache 与 available 一次讲清

我第一次正经看 free -h 的输出,是服务器上跑着个服务、我想确认「内存还够不够」的时候。

复制代码
               total   used   free   shared  buff/cache   available
内存:          7.7Gi  3.1Gi  402Mi  128Mi   4.2Gi        4.3Gi

402Mi 的 free,总内存 7.7Gi------按 Windows 的直觉,「可用内存」只剩 5%。我当时的第一反应是写了个告警脚本:free 低于 500M 就发通知。第二天通知就炸了,而机器跑得好好的。

这篇讲清那个脚本错在哪,以及 free 的输出到底该看哪一列。

〇、先花两分钟:Linux 为什么把「闲内存」都占着

先接受一个反直觉的设计:内存闲着 = 浪费。

CPU 读内存是纳秒级,读磁盘是毫秒级------差五位数 。所以内核的策略是:凡是闲着的内存,统统拿去缓存最近读过的磁盘内容(文件内容缓存叫 page cache,目录元数据那点叫 buff)。下次再读同一个文件,直接从内存出,快一万倍。

那程序真要内存了怎么办?缓存随时可以让位------内核把最久没用的缓存内容扔掉,腾出来的内存立刻分给程序。缓存不是「占用」,是「排队借住」,正主一到就让房。

这就是 free -h 那两列的来历:

  • free:真正空置 的内存(没人用、也没做缓存)------越少越好,因为空着 = 白白浪费;

  • buff/cache:借出去做缓存的内存------可随时回收;

  • available:内核自己估算的「程序现在来要,能立刻给多少 」= free + 可回收的缓存。判断内存够不够,只看这列。

一句话:free 是「空房间」,available 是「想住马上能腾出的房间」。酒店满房不等于住不进人------退房高峰随时有房。

图示:free -h 逐列标注与两个真正该警惕的信号

一、逐列精读 free -h

复制代码
$ free -h
               total    used    free   shared  buff/cache   available
内存:          7.7Gi    3.1Gi   402Mi  128Mi      4.2Gi       4.3Gi
交换:          2.0Gi    0B      2.0Gi

怎么读,一行过一遍:

  • total:物理内存总量(这台 7.7Gi,就是标称 8G 扣掉显存/保留的部分);

  • used:程序真用掉的(不含缓存);

  • free:空置的,别拿它报警;

  • shared:tmpfs 这类共享内存占的,量小通常无视;

  • buff/cache:借出去的缓存,健康机器上它往往很大,是好事;

  • available:唯一值得盯的列------它低于 total 的 10~15% 才说明真紧张;

  • 第二行「交换」是 swap(E4 专门讲):used 为 0B 是常态,不是异常。

顺带一个读数陷阱:free 不带 -h 输出的是 KiB 裸数字,眼花;永远加 -h(human-readable)。

二、实测:手动清缓存是自我感动

网上流传一条「优化命令」:

复制代码
sudo sh -c 'echo 3 > /proc/sys/vm/drop_caches'

它确实会把 page cache 清掉------free 列瞬间变大,buff/cache 列变小。看起来清爽了,实际是性能倒退:缓存清空后,接下来一段时间每次读文件都直连磁盘(iostat 上能肉眼看到读请求暴涨),机器反而变卡。

打个比方:清缓存 = 把图书馆所有还在桌上的书全塞回仓库,只为了看「桌面空了」------下一位读者每本书都要重新去仓库取。

我在自己机器上做过前后对比:清完后重新 cat 一个 500M 的日志文件,耗时是从缓存读的 20 倍以上 。drop_caches 的真实用途是做基准测试前排除缓存干扰,日常「优化」用它属于负面优化。

三、真正该警惕的两个信号

信号 1:available 持续走低 。低于 total 的 10%(比如 8G 机器长期 available < 800M)且仍在下降------这才是「内存真不够」,处理顺序:smem / ps aux --sort=-%mem 看谁吃的 → 该限的限(cgroup/systemd MemoryMax)→ 实在不行加内存。

信号 2:swap 的 used 持续增长且伴随磁盘 IO 高 。内存不够时内核把冷数据挪去 swap(磁盘上),程序碰那些数据时要再搬回来------表现为机器间歇性卡顿。swap 用了不一定是坏事(E4 讲),但「swap 涨 + 磁盘忙 + 卡顿」三件套齐了就是内存真吃紧。看 swap 细节:

复制代码
vmstat 1

怎么读 :看 si/so 两列(swap in/out)------持续非零 = 正在频繁换页,配合卡顿就是实锤。vmstat 是 E2 的主角之一,这里先混个脸熟。

四、和后面几篇的关系

  • vmstat 换页观察在本篇只露了一手,E2 会把它和 iostat/mpstat/sar 凑成性能四件套;

  • swap 到底是敌是友、swappiness 调不调,E4 专门翻案;

  • 「available 低了之后找谁算账」的完整方法论(从 top 到 pidstat 的分层定位),在 E3。

速查表(文末收藏版)

复制代码
看内存              →  free -h    (永远带 -h)
判断够不够          →  只看 available 列!低于 total 的 10~15% 才紧张
free 列很小         →  正常!闲内存被拿去做缓存了,不是快满了
buff/cache 很大     →  好事(磁盘缓存,随时可让位)
手动清缓存          →  echo 3 > /proc/sys/vm/drop_caches 只用于压测前
                       日常跑它 = 性能倒退,不是优化
谁吃了内存          →  ps aux --sort=-%mem | head
swap 频繁换页       →  vmstat 1 看 si/so 持续非零 + 机器卡 = 内存吃紧
危险信号            →  ①available 持续走低 ②swap涨+磁盘忙+卡顿 三件套
相关推荐
灯澜忆梦2 小时前
【docker】#1 | Docker 初识
运维·docker·容器
风寄巴山秋2 小时前
OpenBMC:Web 页面功能异常排查
运维·服务器·前端·架构
xiaoye-duck3 小时前
《Linux 网络编程》深入理解 epoll(下):epoll 实战开发与 LT/ET 触发模式深度剖析
linux·网络
小白的码BUG之路3 小时前
Jenkins -- 连接gitee
运维·gitee·jenkins
峥无3 小时前
Linux线程深度剖析:轻量级进程、虚拟内存分页、进程线程资源对比
linux·运维·mmap
骑着蜗牛撵大象3273 小时前
穿越 Docker 内核迷雾:镜像分层的叠加态与卷挂载的空间穿梭
运维·docker·容器·联合文件系统·卷挂载·镜像分层·存储驱动
honsor3 小时前
以太网温湿度传感器:RJ45直连机房的环境监控新方案
运维·网络·数据库·物联网·安全·云计算·github
zxcvb1534 小时前
规定备份信息的备份方式:从策略制定到自动化落地的实践思考
运维·oracle·自动化