/proc/meminfo

这一节核心解决一个问题:

为什么 MemFree 不等于真正可用内存?

这也是 Linux 内存监控里最容易被问的点。


1. /proc/meminfo 是什么

一句话:

/proc/meminfo 是 Linux 内核暴露当前系统内存状态的接口,里面记录了总内存、空闲内存、可用内存、缓存、Swap、页表、Slab 等信息。

文章里也提到,/proc/meminfo 保存系统当前内存利用状况,常被 free 命令使用,内容通常是“字段名 + 对应值”的形式。

你的性能监控项目里,Worker 内存采集模块会读取 /proc/meminfo,解析 MemTotal、MemFree、MemAvailable、Buffers、Cached 等字段;项目分析里也明确提醒:MemFree 不等于真正可用内存,MemAvailable 更重要。


2. 先看一个典型输出

执行:

cat /proc/meminfo

可能看到:

MemTotal:        8017864 kB
MemFree:          150608 kB
MemAvailable:    1928040 kB
Buffers:           59152 kB
Cached:          2957520 kB
SwapCached:         2304 kB
Active:          5212064 kB
Inactive:        2191888 kB
SwapTotal:       2097148 kB
SwapFree:        1936892 kB
Dirty:              1120 kB
Writeback:             0 kB
Slab:             284820 kB

你作为第一阶段,不需要全部背。

先抓这几个:

MemTotal
MemFree
MemAvailable
Buffers
Cached
SwapTotal
SwapFree
Dirty
Writeback
Slab

3. 最重要的几个字段

字段小白解释监控意义
MemTotal总物理内存分母
MemFree完全没被用的空闲内存不能单独代表可用内存
MemAvailable估算还能分配给新程序的内存判断内存压力最重要
Buffers块设备元数据缓存可回收缓存的一部分
Cached文件页缓存 page cacheLinux 会用它加速文件读写
SwapTotal总交换空间物理内存不够时的后备空间
SwapFree剩余交换空间判断是否大量换页
Dirty已修改但还没写回磁盘的页写回压力
Writeback正在写回磁盘的页I/O 写回状态
Slab内核对象缓存内核态内存消耗

4. 为什么 MemFree 不等于真正可用内存

这是本节最核心的点。

很多小白看到:

MemTotal:     8 GB
MemFree:      150 MB

会以为:

系统快没内存了

这不一定对。

因为 Linux 的设计原则是:

空着的内存是浪费,所以 Linux 会尽量把暂时不用的内存拿来做缓存。

比如:

你第一次读一个大文件
  ↓
Linux 从磁盘读到内存
  ↓
读完后不会马上丢掉
  ↓
它会把文件内容留在 page cache 里
  ↓
下次再读同一个文件,就可以直接从内存读

所以 Linux 里经常会出现:

MemFree 很低
Cached 很高

这通常不是坏事,而是说明 Linux 把空闲内存拿去做缓存了。


5. MemAvailable 才更接近“还能用多少”

MemAvailable 的含义是:

内核估算在不明显触发 Swap 的情况下,还能分配给新程序使用的内存。

它不只是看 MemFree,还会考虑:

当前完全空闲的内存
+
可以回收的 page cache
+
可以回收的一部分 slab
-
为了系统稳定必须保留的水位线

所以你应该这样判断:

字段判断价值
MemFree只表示完全空闲内存,参考价值有限
MemAvailable更适合判断系统是否真的缺内存
Cached/Buffers很多时候可以被回收,不要简单认为是“被浪费”

面试里最重要的一句话:

Linux 内存监控不能只看 MemFree,因为 page cache 和 buffer 可以在内存紧张时被回收;更应该看 MemAvailable。


6. Buffers 和 Cached 区别

小白可以这样理解:

6.1 Buffers

偏向块设备层面的缓存。

比如磁盘块、文件系统元数据相关缓存。

磁盘块设备
  ↓
文件系统元数据 / block buffer
  ↓
Buffers

6.2 Cached

偏向文件内容页缓存,也就是 page cache。

比如你读了一个文件:

磁盘上的 file.txt
  ↓
读到内存
  ↓
放入 page cache
  ↓
Cached 增加

简单记:

Buffers:偏块设备/元数据
Cached:偏文件内容缓存

现在 Linux 里你更常关注 Cached 和 MemAvailable。


7. 内存使用率怎么算

7.1 不推荐的算法

很多人会直接写:

used = MemTotal - MemFree
usage = used / MemTotal

这个算法有问题。

因为它会把 Cached、Buffers 都算成“已经不可用”,导致内存使用率看起来虚高。


7.2 更推荐的算法

面试和监控里更推荐:

used = MemTotal - MemAvailable
usage = used / MemTotal

也就是:

内存使用率 = 1 - MemAvailable / MemTotal

举例:

MemTotal     = 8000 MB
MemFree      = 150 MB
MemAvailable = 2000 MB

如果用 MemFree 算:

usage = 1 - 150 / 8000 = 98.1%

看起来快爆了。

但用 MemAvailable 算:

usage = 1 - 2000 / 8000 = 75%

这更接近真实压力。


8. Swap 怎么看

Swap 是磁盘上的交换空间。

当物理内存紧张时,内核可能把一部分不常用内存页换到 Swap:

物理内存不够
  ↓
内核挑一些冷页
  ↓
写到 Swap
  ↓
释放物理内存

看两个字段:

SwapTotal
SwapFree

可以算:

SwapUsed = SwapTotal - SwapFree

如果出现:

SwapUsed 很高

说明系统可能经历过内存压力。

如果同时:

SwapUsed 持续增长
系统响应变慢
磁盘 I/O 上升

就要警惕内存不足导致频繁换页。

注意:

Swap 用了一点不一定马上有问题,关键看是否持续增长,以及是否伴随 major page fault、I/O 抖动和延迟升高。


9. Dirty 和 Writeback 怎么看

这两个和磁盘写回有关。

9.1 Dirty

表示:

已经被修改,但还没有写回磁盘的内存页

比如程序写文件:

write()
  ↓
先写到 page cache
  ↓
标记为 Dirty
  ↓
后续由内核异步刷盘

9.2 Writeback

表示:

正在被写回磁盘的内存页

如果:

Dirty 很高
Writeback 很高

可能说明:

磁盘写入压力大
后台刷盘跟不上

这时候可能会进一步影响:

iowait
load average
请求延迟

10. Slab 是什么

Slab 是内核对象缓存。

内核经常要创建和释放一些对象,比如:

inode
dentry
socket buffer
task_struct
文件描述符相关结构

如果每次都从通用内存分配器申请释放,成本高。所以 Linux 用 slab/slub allocator 做对象缓存。

小白先这么记:

Slab 是内核自己用的一部分内存,主要缓存内核对象。

Slab 里还有两类常见字段:

SReclaimable
SUnreclaim
字段含义
SReclaimable可回收 slab
SUnreclaim不可回收 slab

如果 SUnreclaim 异常高,可能要怀疑内核态内存泄漏或某类内核对象暴涨。

第一阶段不用深挖,知道它属于内核内存即可。


11. /proc/meminfo 要不要两次采样?

和 /proc/stat 不一样。

CPU 使用率需要两次采样,因为 CPU 字段是累计时间。

但 /proc/meminfo 大部分字段是当前时刻的状态量:

当前总内存是多少
当前可用内存是多少
当前 Cached 多少
当前 Dirty 多少

所以内存使用率通常读一次就能算当前状态:

usage = 1 - MemAvailable / MemTotal

但如果要看趋势,也会周期采样:

每 10 秒采一次
  ↓
观察 MemAvailable 是否持续下降
  ↓
观察 SwapUsed 是否持续上升
  ↓
判断是否存在内存泄漏或压力上升

12. 和前两节怎么联动判断问题

现在你已经学了:

/proc/stat     -> CPU 使用率 / iowait
/proc/loadavg  -> 系统负载
/proc/meminfo  -> 内存状态

可以组合诊断:

现象可能原因
CPU 高,load 高,MemAvailable 正常CPU 计算压力
CPU 不高,load 高,iowait 高I/O 阻塞
MemAvailable 持续下降,SwapUsed 上升内存压力或内存泄漏
Dirty/Writeback 高,iowait 高写盘压力大
Cached 高,MemAvailable 也高正常,Linux 在用缓存提速
MemFree 低,但 MemAvailable 高正常,不要误判内存不足

13. 放到你的性能监控项目里

项目链路可以这样讲:

Worker 定时读取 /proc/meminfo
    ↓
解析 MemTotal / MemAvailable / Buffers / Cached / Swap
    ↓
计算内存使用率
    ↓
MetricCollector 聚合到 MonitorInfo
    ↓
MonitorPusher 通过 gRPC Push 到 Manager
    ↓
HostManager 把内存使用率纳入健康评分
    ↓
写入 MySQL,QueryService 支持历史趋势查询

你的项目源里明确说低频指标包括 /proc/loadavg、/proc/meminfo、/proc/diskstats,Worker 一轮采样后会统一聚合到 MonitorInfo 再发,不是每个指标单独发 RPC。

项目分析里也提到,Worker 端不是单一采集器,而是 CPU、内存、磁盘、网络、eBPF、用户态监控等多个采集模块组合成总的 MonitorInfo;内存采集会读取 /proc/meminfo 并解析 MemTotal、MemFree、MemAvailable、Buffers、Cached 等字段。


14. 面试官可能会问什么

14.1 为什么 free 显示内存快满了,但系统没问题?

答:

因为 Linux 会尽量把空闲内存用作 page cache 和 buffer,加速文件 I/O。MemFree 低不代表系统真的没有可用内存,很多缓存可以在内存紧张时回收。判断真实内存压力更应该看 MemAvailable、Swap 使用情况,以及是否出现持续换页。


14.2 内存使用率应该怎么算?

答:

不建议直接用 MemTotal - MemFree,因为这会把可回收的 page cache 和 buffer 都算成已占用,容易虚高。更合理的是用 MemTotal - MemAvailable,即 usage = 1 - MemAvailable / MemTotal,这样更接近实际内存压力。


14.3 Buffers 和 Cached 有什么区别?

答:

Buffers 更偏块设备和文件系统元数据缓存,Cached 更偏文件内容的 page cache。两者都可能在内存紧张时被回收,所以不能简单把它们都当成不可用内存。


14.4 Swap 使用了是不是一定有问题?

答:

不一定。少量 Swap 使用只能说明系统曾经或当前有过内存回收压力。真正危险的是 Swap 使用持续增长,同时伴随 major page fault、磁盘 I/O 升高、响应延迟变大,这通常说明物理内存不足或进程内存泄漏。


15. 小白最小记忆版

你先背这个:

/proc/meminfo 看当前内存状态。

MemTotal 是总内存。

MemFree 只是完全空闲内存,不等于真正可用内存。

Linux 会把空闲内存用作 Buffers/Cached,提高文件 I/O 性能。

MemAvailable 更接近“还能给新程序用多少内存”。

内存使用率推荐:
usage = 1 - MemAvailable / MemTotal。

SwapUsed = SwapTotal - SwapFree。

MemAvailable 持续下降 + SwapUsed 持续上升,说明内存压力变大。

16. 面试版一句话

/proc/meminfo 记录 Linux 当前内存状态。监控内存时不能只看 MemFree,因为 Linux 会把空闲内存用于 page cache 和 buffer,这些缓存很多在内存紧张时可以回收。更合理的判断方式是看 MemAvailable,内存使用率可以按 1 - MemAvailable / MemTotal 计算。我的项目里 Worker 会读取 /proc/meminfo,解析总内存、可用内存、缓存和 Swap 信息,计算内存压力后封装到 MonitorInfo,再通过 gRPC 上报给 Manager 做健康评分和历史查询。

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐