
本文不教你“怎么看内存占用”,而是讲清楚:
为什么 Linux 内存相关命令,从一开始就“故意让人看不懂”。
一、一个反直觉的现象
为什么 Linux 的 free 总是看起来“快没内存了”?
开篇直接用所有人都踩过的坑:
问题抛出:
结论先行:
这不是 Linux 算错了,而是你理解错了“什么叫内存被用了”。
二、历史背景
UNIX 从一开始,就没打算让“空闲内存”存在
这一节讲设计动机,不是命令。
1️. 早期 UNIX 的现实约束
工程师的共识:
闲着的内存,是浪费。
2. page cache 的诞生
Linux 内存的真实目标不是:
而是:
于是:
这直接决定了:
第一个命令:free
它到底在“统计什么”?
这一节把 free 拆穿。
1️. free 的原始语义
2️.Buff/Cache 的真实含义
- Buffer:块设备元数据; free命令把buffer和cache统计在一起了,要分开了解释,比较容易绕。缓冲区(Buffer)是用于临时存储待写入的块数据到,通常容量不大(约为20MB)。通过这种方式,操作系统内核能够将分散的写入操作集中起来,统一进行优化处理。例如,将多次零散的小规模写入合并为一次大规模写入等。
Buffer vs Cache
- Cache: linux维护四种不同类型cache
1.page cache(页缓存),缓存文件的实际内容,以数据块形式,Linux通常以内存页形式维护(默认为4KB);
2. i-node cache(i节点缓存),缓存最近访问的文件的i-node(文件的元数据meta data,如权限、大小、时间戳、数据块位置等 );
当用户执行 ls -l或程序需要读取文件属性时,内核会先检查i-node Cache
3. buffer cache(缓冲区缓存),与块设备交互,缓存最近使用的磁盘元数据块;
在早期Linux内核中,Buffer Cache是一个独立组件,专门缓存磁盘扇区数据。但在现代Linux内核(2.4版本以后)中,Buffer Cache和Page Cache已经合并 。现在,Buffer Cache可以看作是Page Cache的一部分或一种实现细节:当缓存文件数据时,使用Page Cache;当需要缓存底层的磁盘块(特别是文件系统元数据)时,这部分功能由改进后的Buffer Cache机制处理,但它不再独立存在,而是整合在Page Cache的框架内。
4. directory cache(目录缓存),缓存目录项(包含文件名和对应的inode号),其主要作用是加速文件路径的解析过程。
但在 free 里,它们被算作“已用”。
3️. available 的出现,是一次认错
- 表示: 在不 swap、不 OOM (想了解OOM直接跳OOM Killer章节)的前提下,系统还能给你多少
这是一个典型的:
向历史妥协,又不敢破坏兼容性的产物
第二个命令:vmstat
为什么它不是“看内存”,而是“看行为”?
1️. vmstat 名字的误导性
2️. 你真正该看的字段
si / so:swap in / outbi / bo:block IOin/ cs:interrupt and context switcher
vmstat 的设计哲学:
这个命令很强大,且用且珍惜。
第三个命令:top
为什么 RES / VIRT 几乎永远对不上?
1️. VIRT(virtual memory):一场“合法的欺骗”
它回答的不是:
而是:
2️. RES(Resident memory):你以为的“真实内存”,也不完全真实
Top命令注解
所以:
一个专门为“补锅”而生的命令:smem
为什么它存在?
因为:
smem 的方案:
- Resident Set Size RSS(常驻内存集):
快速查看进程大致的内存占用,是 top、ps等工具的默认指标之一
- Proportional Set Size PSS(比例驻留内存集):
评估系统整体内存压力,是 Android 等系统决定终止哪个进程以释放内存的关键依据
- Unique Set Size USS(唯一驻留内存集):
这是 Linux 内存世界里非常罕见的“坦诚”。
知道了这么多,你还要知道:
它其实还很好玩,可以有图有真相:
smem 饼状图
smem 柱状图
OOM Killer
Linux 为什么宁愿杀进程,也不让系统慢慢死?
这一节是情绪记忆点。
1️. overcommit 是默认策略
2️. swap 到死 vs 直接杀
Linux 的选择:
3️. OOM score 的“冷酷数学”
- 哪个占得多 (RSS=anon-rss+file-rss ,RSS上升最快的进程,会死得最快)
| Importance for OOM Killer | |
|---|
| anon-rss 进程独占的物理内存,如堆(heap)和栈(stack) | 极高。这是OOM Killer最关心的“硬”内存消耗,无法被回收。 | 已经实际消耗掉的、无法再给别人的“食材”,比如已经用掉的油和炒好的菜。 |
| file-rss 被映射到物理内存中的文件内容,如程序代码、共享库。 | 较低。这部分内存在紧张时可以被回收(丢弃后能从文件重新读取),因此对OOM的压力较小。 | 那些还未拆封的“预制菜”或“罐头”,在厨房空间不足时可以先挪出去。 |
一个完整的小故事:
当你敲下 free,内核到底在干嘛?
串一次完整路径:
/proc
由于历史硬件原因,系统物理内存被划分为不同的区域(如 DMA、Normal、HighMem等)。/proc/meminfo中的 MemTotal就是对这些区域容量进行统计汇总的结果
下一篇我会写:Process & Scheduling(进程与调度),也许“你看到的进程,都是幻象”
参考文献:
The Linux Kernel's VFS Layer
SRP Technology - Difference between Buffer and Cache!! ..... | Facebook
Unleashing the Power of the Linux ‘top’ Command: A Comprehensive Guide | by Extio Technology | Medium
Smem Tool To Display Memory Usage More Accurate in Linux - GeeksforGeeks