Linux free 命令深度解析:从内存监控到 OOM 排查的完整指南

0 阅读4分钟

服务器又 OOM 了?用 top 看半天没搞懂内存到底去哪了。后来才发现,free 命令才是内存分析的正确姿势。这次把 free 的原理和实战技巧整理一下。

摘要free 命令是 Linux 内存分析的利器。本文深入解读 free -h 输出的四行含义,揭示 buff/cacheavailable 的关键区别;解析其数据来源 /proc/meminfo 及核心计算逻辑;详解 -h-s-t-w 等常用参数;并通过判断内存紧张、Swap 分析、缓存观察、主动释放缓存、监控脚本等实战场景,帮助读者避开常见误区,真正掌握内存分析的正确姿势。

free 输出的四行含义

$ free -h
              total        used        free      shared  buff/cache   available
Mem:           15Gi       8.5Gi       1.2Gi       256Mi       5.3Gi       5.8Gi
Swap:         2.0Gi       512Mi       1.5Gi

很多人看到这个输出就懵了:used + free 怎么不等于 total?available 又是什么?

关键在于 buff/cache 这列。Linux 会把空闲内存拿来做缓冲区(buffer cache)和页面缓存(page cache),加速文件读写。所以:

  • free:完全没被使用的内存
  • buff/cache:用于缓存的内存(可以释放)
  • available:程序实际可申请的内存(free + 可回收的 cache)

真正判断内存是否紧张,看 available,不是 free。

/proc/meminfo:free 的数据来源

free 命令的数据来自 /proc/meminfo

$ head -20 /proc/meminfo
MemTotal:       16384000 kB
MemFree:         1228800 kB
MemAvailable:    6029312 kB
Buffers:          524288 kB
Cached:          5242880 kB
SwapCached:            0 kB
Active:          4194304 kB
Inactive:        3145728 kB

free 命令的核心逻辑就是读取这些字段并格式化输出:

// free 命令源码简化逻辑
void print_meminfo() {
    FILE *fp = fopen("/proc/meminfo", "r");
    unsigned long mem_total, mem_free, buffers, cached;

    // 逐行解析
    while (fgets(line, sizeof(line), fp)) {
        if (sscanf(line, "MemTotal: %lu kB", &mem_total));
        else if (sscanf(line, "MemFree: %lu kB", &mem_free));
        else if (sscanf(line, "Buffers: %lu kB", &buffers));
        else if (sscanf(line, "Cached: %lu kB", &cached));
    }

    // 计算公式
    unsigned long used = mem_total - mem_free - buffers - cached;
    unsigned long buff_cache = buffers + cached;

    printf("Mem: %lu %lu %lu %lu %lu\n",
           mem_total, used, mem_free, buff_cache, ...);
}

available 的计算更复杂,涉及 MemAvailable 字段(内核 3.14+)或估算可回收内存。

常用参数详解

-h:人类可读格式

$ free -h
Mem:   15Gi  8.5Gi  1.2Gi  256Mi  5.3Gi  5.8Gi

自动转换单位(K/M/G/T),比 -m(MB)、-g(GB)智能。

-b/-k/-m/-g:指定单位

$ free -m  # 以 MB 显示
$ free -g  # 以 GB 显示
$ free -b  # 以字节显示

写监控脚本时,用 -b 方便计算百分比。

-s N:持续监控

$ free -s 1  # 每秒刷新
$ free -s 5 -c 10  # 每 5 秒刷新,共 10 次

配合 -c 限制次数,避免无限循环。

-t:显示总计

$ free -t
              total        used        free      shared  buff/cache   available
Mem:        16384000     8847360     1257472      262144     6279168     6029312
Swap:        2097152      524288     1572864
Total:      18481152     9371648     2830336

多一行 Mem + Swap 的总计。

-w:宽输出,分开显示 buffer 和 cache

$ free -w
              total        used        free      shared     buffers       cache   available
Mem:        16384000     8847360     1257472      262144      524288     5754880     6029312

buffers 是块设备缓存,cache 是文件系统缓存,分开看更清晰。

实战场景

1. 判断内存是否紧张

$ free -h
Mem:   15Gi  14Gi  512Mi  256Mi  512Mi  400Mi

available 只有 400Mi,说明内存紧张,但还没 OOM。这时候就该扩容或优化了。

2. Swap 使用分析

$ free -h
Swap:  2.0Gi  1.8Gi  200Mi

Swap 用了 90%,说明内存严重不足,系统在频繁换页。性能会急剧下降。

3. 观察缓存效果

# 第一次读取大文件
$ time cat 10GB.log > /dev/null
real    0m45.123s

# 第二次读取(缓存命中)
$ time cat 10GB.log > /dev/null
real    0m2.456s

# 观察缓存增长
$ free -h
buff/cache 从 5.3Gi 增长到 10.2Gi

Linux 自动用空闲内存做缓存,加速文件访问。

4. 主动释放缓存

# 释放 page cache
$ echo 1 > /proc/sys/vm/drop_caches

# 释放 dentries 和 inodes
$ echo 2 > /proc/sys/vm/drop_caches

# 释放所有缓存
$ echo 3 > /proc/sys/vm/drop_caches

注意:生产环境慎用,会影响性能。sync 命令先同步数据:

$ sync && echo 3 > /proc/sys/vm/drop_caches

5. 监控脚本示例

#!/bin/bash
# 内存监控脚本

THRESHOLD=90  # 内存使用阈值

while true; do
    MEM_INFO=$(free | grep Mem)
    TOTAL=$(echo $MEM_INFO | awk '{print $2}')
    USED=$(echo $MEM_INFO | awk '{print $3}')

    PERCENT=$(echo "scale=2; $USED * 100 / $TOTAL" | bc)

    if (( $(echo "$PERCENT > $THRESHOLD" | bc -l) )); then
        echo "$(date): Memory usage ${PERCENT}% exceeds threshold!"
        # 发送告警
    fi

    sleep 60
done

常见误区

1. free 很少就是内存不足

恰恰相反,Linux 的设计理念是"空闲内存是浪费"。free 少说明缓存利用充分。

2. used 很高就是内存紧张

不对。used 包含了 buff/cache,这部分内存可以立即释放。

判断标准:看 available,不是 free 或 used。

3. Swap 用了就有问题

不一定。少量 Swap 使用是正常的,比如休眠到磁盘的程序。关键是 Swap 是否在增长。

free 与其他工具对比

工具优势场景
free快速总览日常检查
top/htop实时进程排序找内存大户
vmstat详细的内存统计性能分析
/proc/meminfo完整的内存信息深度诊断
smem进程实际内存(PSS)精确统计

smem 按 PSS(Proportional Set Size)统计,比 top 的 RES 更准确:

$ smem -t -k -s rss
  PID User     Command     Swap  USS    PSS    RSS
12345 nginx    nginx       0     45M    52M    68M

小结

free 命令虽小,但读懂它需要理解 Linux 内存管理机制:

  • available 判断内存是否紧张
  • buff/cache 是好东西,别看到 free 少就慌
  • Swap 使用率持续增长才是危险信号
  • 配合 /proc/meminfo 做深度诊断

下次遇到 OOM,先用 free -h 看看整体情况,再用 smemhtop 找具体进程。


相关工具:Linux df 磁盘空间监控 | Linux du 目录大小统计
在这里插入图片描述