Appearance
内存使用指标 —— free、cache、buffer、swap、缺页、OOM
free -h看到available比free大很多是怎么回事?cache高了要不要清?Swap 用了 30% 是不是内存不够了?page fault分 major 和 minor——哪个才需要关注?OOM Killer 又是根据什么挑进程杀的?本文拆解内存相关的全部指标。
更新时间:2026-08-06
一、全局内存指标——来自 /proc/meminfo
/proc/meminfo 是内存指标的"总目录",free、vmstat、top、sar -r 全部从这里读取。以下是排查中最常用的字段:
1.1 核心容量指标
| 字段 | 含义 | 工具列名 |
|---|---|---|
MemTotal | 系统物理内存总量(不含内核预留) | total |
MemFree | 完全没有被使用的物理内存 | free |
MemAvailable | 估算:新进程可以不经过 swap 直接申请到的内存(包括可回收的 cache/buffer) | available |
Buffers | 块设备元数据缓存(inode、dentry 等,即 buffer_head) | buff/cache 的一部分 |
Cached | 页缓存(Page Cache,文件内容缓存) | buff/cache 的一部分 |
SwapTotal | 交换空间总大小 | total(swap 行) |
SwapFree | 交换空间空闲大小 | free(swap 行) |
MemFree vs MemAvailable:
MemFree是"真·没人用的内存",MemAvailable是"可回收后可用的内存"(包括可以释放的 Page Cache、可回收的 slab)。判断内存是否够用应看MemAvailable而非MemFree。当MemAvailable接近 0,系统即将开始 swap 或触发 OOM。
1.2 进程内存分解
| 字段 | 含义 |
|---|---|
AnonPages | 匿名页(堆、栈、mmap 匿名映射),不在文件系统中 |
Mapped | 文件映射页(mmap 文件到内存的页面) |
Shmem | 共享内存(tmpfs、System V shm、POSIX shm),存在于 Page Cache 中但不可回收 |
Slab | 内核 slab 分配器占用的内存(包括 dentry、inode_cache 等内核对象缓存) |
KernelStack | 每个线程的内核栈内存 |
PageTables | 页表本身占用的内存 |
二、为什么 free 显示的 free 很小但内存不紧张?
Linux 的原则是"空闲内存是浪费的内存"。内核会把不用的物理内存自动用作页缓存(Page Cache)——读过的文件内容缓存在内存中,下次读取直接从内存返回,不需要磁盘 I/O。
物理内存 = 已使用(进程+内核) + Page Cache + 真正的空闲
\_____________ ______________/
v
可回收(MemAvailable 覆盖的范围)只有当进程需要更多内存、且 Page Cache 已经不够回收时,才触发 swap 换出或 OOM Kill。
判断规则:
MemAvailable才是可用内存的底线。只要available还充裕,free为 0 也不要紧。
三、Swap 指标:使用了不代表内存不够
3.1 相关字段
| 字段 | 含义 |
|---|---|
SwapTotal | swap 分区/文件总大小 |
SwapFree | swap 空闲空间 |
SwapCached | 曾经被 swap out、现在又 swap in 回来但仍在 swap 中保留副本的页面 |
3.2 Swap 使用 = 内存不够?
不一定。内核对 swap 的策略是"倾向"或"不倾向",由 vm.swappiness 控制:
swappiness接近 0:内核尽量不 swap,除非不 swap 就 OOMswappiness接近 100:内核积极将不活跃的匿名页换出,腾出更多内存给 Page Cache
Swap 用了 30% 但 available 还很充裕?那是内核的"预换出"——把长期不用的页面挪到 swap,腾空间给活跃数据。只有当 Swap 持续增长 + available 持续下降时,才是真正的内存不足。
3.3 更值得关注的指标
| 指标 | 含义 | 危险信号 |
|---|---|---|
si(swap in)/ so(swap out) | swap 读写速率(vmstat 的 si/so 列) | so 持续 > 0 → 内存压力大 |
pgmajfault/s | major page fault 速率 | > 100/s → swap 频繁,严重影响性能 |
四、Page Fault(缺页中断)—— minor vs major
当进程访问一个虚拟地址时,如果对应的物理页不在内存中,CPU 触发缺页中断,内核负责把页面加载回来。根据页面在哪里,分为两种:
| 类型 | 页面位置 | 开销 | 是否影响性能 | 统计字段 |
|---|---|---|---|---|
| Minor | 已在内存中,只是页表没映射(如 COW、刚 mmap 的文件但还没读) | 极低(仅页表操作) | 否 | /proc/vmstat:pgfault |
| Major | 在磁盘上(swap 分区或文件系统中) | 极高(磁盘 I/O + 上下文切换) | 是 | /proc/vmstat:pgmajfault |
排查命令:
bash
# 系统级 major page fault 速率
sar -B 1
# 进程级 major page fault
pidstat -r 1实战判断:
sar -B输出中fault/s包含 minor + major,单独看意义不大。关注majflt/s——如果持续 > 50/s,说明有进程正在频繁触发磁盘读(可能是 mmap 大文件随机访问,或者是 swap 换入)。
五、OOM Killer 相关指标
当系统物理内存 + swap 全部耗尽,内核触发 OOM Killer(Out of Memory Killer,内存耗尽杀手) 选择一个进程杀掉以释放内存。
5.1 OOM Score
每个进程有一个 oom_score(0~1000),分数越高越容易被杀:
bash
cat /proc/<pid>/oom_score # 当前评分
cat /proc/<pid>/oom_adj # 调整值(-17 到 +15,-17 完全免疫)评分公式:主要依据进程的内存占用比例(RSS + swap + 页表),并乘以"已运行时间"等惩罚因子。占用越多、子进程越多,分数越高。
5.2 排查 OOM
bash
dmesg | grep -i "killed process" # 查看 OOM Killer 历史
dmesg | grep -i "oom" # 查看完整 OOM 日志(含各进程评分)六、常见排查模式速查
| 现象 | 工具 | 关注指标 | 排查方向 |
|---|---|---|---|
| 内存"看起来"不够 | free -h | available vs free | available 大就没事,Linux 会把空闲内存用作 cache |
| 内存真的不够 | free -h;sar -r 1 | available 持续下降 | 查是否有内存泄漏(top -o RES 看 RSS 持续增长) |
| swap 在涨 | vmstat 1 | si/so、swpd | si/so > 0 → 正在换入换出,性能受影响 |
| OOM 被杀了 | dmesg | Out of memory | 看被杀进程的 oom_score,增加内存 / 降低进程内存 / 调 oom_score_adj |
| slab 占用高 | cat /proc/meminfo | Slab | slabtop 查看 dentry/inode cache 是否异常,echo 2 > /proc/sys/vm/drop_caches 释放 |
| 进程内存持续增长 | pidstat -r 1 | RSS、VSZ | 内存泄漏,valgrind / heaptrack 定位 |
七、一句话总结
内存指标的核心判断从 MemAvailable 开始——它才是新进程能直接用的内存。Swap 用了不代表不够(可能是预换出),只有 si/so 持续 > 0 才说明内存压力真的来了。Minor page fault 是正常现象不用管,Major page fault 才是需要关注的磁盘 I/O 来源。OOM Killer 按 oom_score(主要依据内存占用)选进程杀,oom_score_adj = -1000 可完全免疫。