内存往往是系统性能中最容易被误判的资源。看到“内存使用率 95%”并不一定意味着内存不足,因为 Linux 会积极利用空闲内存作为缓存来加速 I/O,这部分缓存可以在应用需要时快速回收。真正的内存瓶颈通常表现为频繁的交换(swap)、严重的性能抖动,甚至 OOM(Out of Memory)进程被杀。
1. 先看全局:free 与 /proc/meminfo
free -h 是最快的概览工具,能显示总量、已用、空闲、共享、缓存和可用内存。
free -h
输出中要特别关注 available 这一列,它估算出在不触发交换的情况下,还能分配给新进程的内存量。它与 free 不同,free 只算完全未用的内存,而 available 还考虑了可回收的缓存和缓冲区。如果 available 持续偏低(例如小于总内存的 5%~10%),就可能需要关注。
更详细的信息在 /proc/meminfo 中:
cat /proc/meminfo
其中几个关键项:
MemTotal/MemFree/MemAvailable:总、空闲、可用。Buffers/Cached:分别缓存文件系统元数据和文件内容,属于可回收内存。SwapTotal/SwapFree:交换空间的使用情况。Dirty:已修改但尚未写回磁盘的页,过多可能导致 I/O 阻塞。Slab:内核数据结构缓存,若持续增长可能是内核对象泄漏的信号。
2. 动态监控:top / htop / vmstat
top 或 htop 能实时显示进程内存占用(RES 表示物理内存,VIRT 为虚拟内存),同时关注 swap 行。如果 swap 使用量不断增长,很可能是内存压力在上升。
vmstat 适合观察趋势与系统整体行为:
vmstat 1
重点关注 swap 列的 si(swap in)和 so(swap out)。如果这两者持续非零,说明系统正在反复换入换出页面,性能会急剧下降。free 列表示空闲内存,buff 和 cache 表示缓冲和缓存。si/so 才是内存不足的真正警铃。
3. 定位“吃内存”的进程
- 按物理内存排序:在
top中按M(大写)即可按内存使用量排序。 - 更精准的查询:
ps aux --sort=-%mem | head -n 10
这列出物理内存占用最高的进程。
- 查看具体进程的详细内存映射:
cat /proc/<PID>/smaps
pmap -x <PID>
可以看到堆、栈、共享库、匿名内存等的分布,有助于发现内存泄漏区域。
4. 识别内存泄漏与异常
如果某个进程的 RES 随时间单调增长且从不下降,就可能存在泄漏。简单观测方法:
while true; do ps -p <PID> -o rss= >> rss.log; sleep 10; done
之后对日志绘图或简单计算增长率。对于更专业的调试,可以使用 valgrind --leak-check=full 或 AddressSanitizer 来分析应用程序。
内核泄漏可观察 Slab 值是否异常上涨(/proc/meminfo 中的 SReclaimable / SUnreclaim)。可使用 slabtop 命令查看内核缓存的使用排行。
5. 交换与 OOM 的处理
当内存彻底耗尽,内核的 OOM Killer 会强制击杀进程以释放内存。dmesg | grep -i oom 可以找到相关记录和评分。
如果系统频繁触发 OOM 或严重换页,一般应从以下几方面入手:
- 调整应用的内存使用(减少并发、修复泄漏)。
- 增加物理内存。
- 若有明显 cache 占用大但应用需要内存,可手动清理缓存(
echo 3 > /proc/sys/vm/drop_caches,仅用于临时调试,不宜长用)。 - 调整
vm.swappiness(默认60),降低该值可减少内核将匿名页换出的倾向,让系统更倾向于回收文件缓存。 - 合理设置 OOM 调整值(
/proc/<PID>/oom_score_adj)保护关键服务。
6. 快速检查清单
当怀疑内存性能问题时,可以按以下顺序排查:
free -h确认available是否极低。vmstat 1查看si/so是否持续非零。top找出内存占用大户,确认其增长趋势。cat /proc/meminfo观察Dirty、Slab等是否有异常。dmesg | grep -i oom查看是否有进程被杀历史。- 结合应用程序日志或内存分析工具,确认是配置不足、泄漏还是正常高负载。
内存分析不靠直觉,而在于理解“用了多少”和“可回收多少”之间的区别。Linux 的透明性让你几乎可以通过简单的文本读取获得一切需要的信息,关键在于知道该看哪些指标以及它们各自的意义。