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

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

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

free 输出的四行含义

bash 复制代码
$ 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

bash 复制代码
$ 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 命令的核心逻辑就是读取这些字段并格式化输出:

bash 复制代码
// 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:人类可读格式

bash 复制代码
$ 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:指定单位

bash 复制代码
$ free -m  # 以 MB 显示
$ free -g  # 以 GB 显示
$ free -b  # 以字节显示

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

-s N:持续监控

bash 复制代码
$ free -s 1  # 每秒刷新
$ free -s 5 -c 10  # 每 5 秒刷新,共 10 次

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

-t:显示总计

bash 复制代码
$ 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

bash 复制代码
$ free -w
              total        used        free      shared     buffers       cache   available
Mem:        16384000     8847360     1257472      262144      524288     5754880     6029312

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

实战场景

1. 判断内存是否紧张

bash 复制代码
$ free -h
Mem:   15Gi  14Gi  512Mi  256Mi  512Mi  400Mi

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

2. Swap 使用分析

bash 复制代码
$ free -h
Swap:  2.0Gi  1.8Gi  200Mi

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

3. 观察缓存效果

bash 复制代码
# 第一次读取大文件
$ 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. 主动释放缓存

bash 复制代码
# 释放 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 命令先同步数据:

bash 复制代码
$ sync && echo 3 > /proc/sys/vm/drop_caches

5. 监控脚本示例

bash 复制代码
#!/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 更准确:

bash 复制代码
$ 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 目录大小统计

相关推荐
A小辣椒1 天前
TShark:Wireshark CLI 功能
linux
A小辣椒1 天前
TShark:基础知识
linux
AlfredZhao1 天前
OCI 明明分配了 200G 系统盘,为什么 df 只看到 30G?
linux·oci
AlfredZhao2 天前
vi 删除指定范围的行,不用再反复按 dd
linux·vi
用户9718356334662 天前
银河麒麟 KY10 申威(SW64) 安装 nginx-1.16.1-2.p01.ky10.sw_64.rpm 详细步骤
linux
猪脚踏浪2 天前
linux 拷贝文件或目录到指定的位置
linux
摇滚侠3 天前
Linux CentOS7 rpm 安装 MySQL 5.7
linux·运维·mysql
bush43 天前
嵌入式linux学习记录十四、术语
linux·嵌入式
载数而行5203 天前
Linux 11 动态监控指令top
linux
不会C语言的男孩3 天前
Linux 系统编程 · 第 8 章:进程基础
linux·c语言