available 列才是真正的可用内存,它由内核估算可立即分配而不触发 oom 的量;memfree+buffers+cached 不可简单相加,因存在重复计算和不可回收页;/proc/meminfo 中 memavailable 与 free 命令的 available 值应一致,差异多源于刷新延迟或工具版本。

free 命令输出里 buffers 和 cached 到底算不算“可用内存”
算,但得看 Linux 版本和内核参数。2.6.27 之后的内核把 cached(页缓存)和 buffers(块设备缓冲区)都归入可快速回收的内存池,free 命令的 available 列就是专门为此设计的——它估算当前能立刻分配给新进程而不触发 OOM 的内存大小。
常见错误是盯着 free 列的数字猛看,以为那就是“空闲内存”。其实那个值只包含完全没被使用的物理页,Linux 几乎从不长期保留这种状态;真正关键的是 available 列(>= 3.14 内核默认显示)。
- 如果
available明显低于应用常驻内存需求(比如 Java 堆设了 4G,available只剩 1.2G),说明系统已逼近压力点 -
cached高 ≠ 内存泄漏,它只是文件读写缓存,进程需要时内核会自动回收 - 老内核(如 RHEL 6 的 2.6.32)没有
available列,得靠grep -i "memavailable" /proc/meminfo查,若无此字段,则用free + buffers + cached粗略估算(但偏乐观)
/proc/meminfo 里 MemAvailable 为什么比 free 命令的 available 小
不会。正常情况下二者数值一致——因为 free 命令的 available 列直接读的就是 /proc/meminfo 中的 MemAvailable 字段。如果你看到差异,大概率是时间差或工具版本问题。
常见错误现象:free -h 输出 available 是 3.2G,而 cat /proc/meminfo | grep MemAvailable 显示 2.8G。这通常是因为:
-
free默认每秒刷新一次,你执行两次命令之间内核已回收/分配了部分缓存 - 某些定制版
free(如 BusyBox)不支持MemAvailable,会退化为旧算法计算,结果不可比 -
/proc/meminfo是实时快照,free可能做了四舍五入(比如显示 3.2G 实际是 3215MB,而MemAvailable:行写的是 3142000 kB)
MemFree、Buffers、Cached、SReclaimable 这几个字段的关系
它们代表不同层级的“可回收性”,不是简单相加关系。内核内存管理把缓存分成了有明确归属和无明确归属两类:
-
MemFree:完全未使用的物理页,极少,通常几百 MB 就算多 -
Buffers:块设备 I/O 的临时缓冲(如 ext4 日志、磁盘元数据),可立即回收 -
Cached:传统意义上的页缓存(文件内容),其中一部分属于可回收的 slab 对象,体现在SReclaimable -
SReclaimable:slab 分配器中可被回收的缓存(如 dentry、inode),它已被计入Cached,**不能重复加到可用内存里**
所以别用 MemFree + Buffers + Cached 当可用内存——这样高估了,因为 Cached 里混着不可轻易动的 dirty page 和 locked page;MemAvailable 才是内核自己跑过回收模拟后给出的靠谱值。
为什么 top 或 ps 看到的进程 RSS 加起来远超 MemTotal
因为 RSS(Resident Set Size)统计的是进程独占的物理内存页,但很多页是共享的——比如多个 Java 进程共用同一份 JRE 类库内存,或动态链接的 libc.so 被几十个进程映射,这些页在 RSS 中被重复计算。
更关键的是,/proc/meminfo 的 MemTotal 是物理内存总量,而 RSS 总和反映的是“进程视角的驻留页总数”,两者维度不同:
- 一个 mmap 共享内存段被 5 个进程映射,RSS 各算一遍,但物理内存只占一份
- tmpfs 文件系统占用的内存也计入
Shmem字段,但它既不在任何进程 RSS 里,也不在MemFree里 - 内核模块、硬件保留内存(如 GPU 显存)、未释放的 slab(
SUnreclaim)都不出现在用户进程 RSS 中
想看真实内存分布,优先盯 MemAvailable 和 /proc/meminfo 各字段总和是否接近 MemTotal;RSS 总和只是辅助判断进程是否异常膨胀的线索,不是内存水位表。










