3. 内存分析工具入门:使用 /proc/meminfo、free -m、smem 查看内存分布
做嵌入式内存优化,第一步不是动手改代码。
而是先搞清楚——内存到底去哪了?
我见过太多工程师,上来就怀疑自己代码有内存泄漏,结果一查,是内核占了一大块。所以,学会用工具看内存分布,是基本功。
3.1 /proc/meminfo:最原始的内存快照
这个文件,说白了就是内核给你的一张内存账单。
你只要敲一行命令:
cat /proc/meminfo
就能看到一大堆指标。但别被吓到,我们重点关注这几个:
| 字段 | 含义 | 我的关注点 |
|---|---|---|
| MemTotal | 物理内存总量 | 确认硬件容量 |
| MemFree | 完全空闲的内存 | 如果接近0,不一定有问题 |
| Buffers | 块设备缓存 | 文件系统相关 |
| Cached | 页面缓存 + tmpfs | 这部分可以回收 |
| SwapTotal / SwapFree | 交换分区总量和剩余 | 边缘设备尽量别用swap |
核心公式:
实际可用内存 ≈ MemFree + Buffers + Cached
因为 Buffers 和 Cached 在内存紧张时可以被内核回收。
我个人习惯,先看 MemAvailable 这个字段。它是内核帮你算好的「预估可用内存」,比你自己加来加去更准。
小技巧:
如果你只想看某个字段,可以配合 grep:
cat /proc/meminfo | grep MemAvailable
3.2 free -m:更友好的命令行工具
/proc/meminfo 信息太原始了。你想想看,每次都要自己算,多麻烦。
所以 Linux 提供了 free 命令。加上 -m 参数,以 MB 为单位显示:
free -m
输出大概是这样的:
total used free shared buff/cache available
Mem: 1984 456 234 34 1294 1345
Swap: 0 0 0
这里有个坑,我刚开始做嵌入式时经常搞混。
你看那个 used 列,它其实包含了 buff/cache。所以 used + free 并不等于 total。
真正该看的是 available 列——它表示在不触发 swap 的情况下,还能给新进程分配多少内存。
避坑指南:
我曾经在一个项目里,看到 free 显示 used 高达 80%,以为内存不够了。后来才发现,大部分是 buff/cache,available 还有 60%。
所以,别被 used 吓到。先看 available。
3.3 smem:按进程看内存,更直观
free 和 /proc/meminfo 只能看全局。但问题往往出在某个进程上。
这时候,smem 就派上用场了。
smem 不是系统自带的,需要安装:
sudo apt install smem # Debian/Ubuntu
sudo yum install smem # CentOS/RHEL
安装后,直接运行:
smem
它会按 RSS、PSS、USS 三个维度,列出每个进程的内存占用。
| 指标 | 全称 | 含义 |
|---|---|---|
| RSS | Resident Set Size | 进程占用的物理内存(包含共享库) |
| PSS | Proportional Set Size | 按比例分摊共享库后的内存 |
| USS | Unique Set Size | 进程独占的物理内存 |
我个人最常用的是 PSS。为什么?
你想想看,两个进程都用了 libc.so,RSS 会重复计算。但 PSS 会把共享库按进程数分摊。这样加起来,才接近系统总内存。
实战用法:
按内存占用排序,找出「内存大户」:
smem -rs pss | head -20
-r 表示倒序,-s pss 表示按 PSS 排序。
嗯,这里要注意。smem 在嵌入式设备上可能跑得比较慢。如果设备内存只有 256MB,建议用 smem -t 只显示 totals,或者干脆用 top 先粗筛一遍。
3.4 三个工具怎么配合?
我一般按这个流程来:
- 先看全局:free -m 扫一眼 available,心里有个底。
- 再查细节:cat /proc/meminfo 确认 Buffers 和 Cached 的分布。
- 最后定位进程:smem -rs pss 找出谁在吃内存。
举个例子。有一次,我发现设备运行 3 天后,available 从 500MB 掉到了 100MB。
用 free -m 一看,Cached 涨了 300MB。再用 smem 一查,发现是一个日志进程不停地写文件,导致页面缓存暴涨。
解决方案很简单:限制日志文件大小,或者定期 sync 并 drop_caches。
补充命令:
如果你想手动清理缓存(仅限调试用):
echo 3 > /proc/sys/vm/drop_caches
但千万别在生产环境乱用。我曾经手滑过,结果系统性能骤降,因为所有缓存都被清空了。
3.5 小结
这三个工具,是内存分析的入门三板斧。
/proc/meminfo 给你原始数据,free -m 给你友好视图,smem 帮你定位进程。
记住一句话:先看 available,再看 PSS,最后动手优化。
下一章,我们会深入讲 slabtop 和 /proc/slabinfo,专门对付内核态的内存泄漏。到时候你会发现,用户态那点内存占用,其实都是小意思。