在Linux系统管理和性能调优中,准确理解内存使用情况是每个运维工程师和开发者的基本功。系统内存状态不仅影响应用程序性能,更是排查各类问题的关键指标。Linux提供了多种内存监控工具,其中/proc/meminfo和free命令是最基础也最常用的两种方式。
我曾在处理一次线上服务崩溃时深刻体会到这两者的区别。当时服务日志显示"内存不足",但free命令显示仍有可用内存。直到查看/proc/meminfo才发现是slab缓存占用过高,这才是真正的"元凶"。这个经历让我明白:不同工具适用于不同场景,理解它们的底层原理和数据来源至关重要。
/proc/meminfo是Linux虚拟文件系统(procfs)中的一个特殊文件。与普通文件不同,它并不实际占用磁盘空间,而是内核内存状态的动态映射。每次读取这个文件时,内核都会实时生成最新数据。
注意:procfs中的文件大小通常显示为0,这是正常现象。它们的内容是在读取时由内核动态生成的。
让我们深入解析几个核心指标及其实际意义:
MemTotal:系统总物理内存。这个值可能略小于硬件规格,因为内核会保留部分内存用于自身运行。
MemFree:完全未被使用的内存。但Linux会尽可能利用空闲内存做缓存,所以这个值通常很小且参考价值有限。
MemAvailable(内核3.14+):这是最值得关注的指标,表示应用程序实际可用的内存。它估算的是:
code复制MemAvailable ≈ MemFree + 可回收的页面缓存 + 可回收的slab内存
Buffers:块设备(如磁盘)的缓冲区,用于暂存待写入的数据。在现代内核中这个值通常较小。
Cached:页面缓存,包含从磁盘读取的文件内容。这是Linux内存利用的关键机制 - 空闲内存会自动用于缓存,提升IO性能。
SwapCached:已被换出到swap但又被换回的内存。这部分内存仍保留在swap空间中,可以快速再次换出。
除了基本指标,/proc/meminfo还包含许多高级内存管理数据:
Slab:内核对象缓存的内存占用。在某些场景下(如大量小文件操作),这部分可能占用较多内存。
SReclaimable:可回收的slab内存。当系统需要更多内存时,这部分可以被回收利用。
CommitLimit和Committed_AS:与overcommit机制相关,用于评估系统内存承诺量。
HugePages系列:大页内存的分配和使用情况,对数据库等内存密集型应用很重要。
free命令实际上是对/proc/meminfo的二次加工。它的核心逻辑是:
/proc/meminfo获取原始数据关键计算公式:
code复制used = MemTotal - MemFree - Buffers - Cached
available = MemAvailable (直接取自/proc/meminfo)
buff/cache = Buffers + Cached
free命令默认输出包含两行:
各列含义:
free命令提供多个实用选项:
-h:人类可读格式(自动选择GB/MB/KB)
bash复制free -h
输出示例:
code复制 total used free shared buff/cache available
Mem: 15Gi 8.2Gi 1.0Gi 456Mi 5.8Gi 6.7Gi
Swap: 2.0Gi 345Mi 1.7Gi
-s:间隔秒数持续监控
bash复制free -s 5 -h # 每5秒刷新一次
-t:显示总计行(物理内存+swap)
bash复制free -th
| 特性 | /proc/meminfo | free命令 |
|---|---|---|
| 数据来源 | 直接来自内核 | 解析/proc/meminfo |
| 详细程度 | 30+个原始指标 | 6-8个汇总指标 |
| 更新频率 | 实时(每次读取) | 实时(但可能有缓存) |
| 计算需求 | 需手动计算 | 自动计算关键指标 |
| 易读性 | 原始数据(需解析) | 格式化输出(支持单位转换) |
| 脚本友好 | 是(易于grep/awk处理) | 需要解析表格格式 |
| 适用场景 | 深度分析、脚本编程 | 快速查看、日常监控 |
使用/proc/meminfo的场景:
使用free命令的场景:
获取内存使用率(适合脚本):
bash复制awk '/MemTotal/{total=$2}/MemAvailable/{avail=$2}END{printf "%.1f%%\n", (total-avail)/total*100}' /proc/meminfo
监控内存趋势变化:
bash复制watch -n 1 'free -h; echo; awk "/MemTotal|MemFree|MemAvailable|Buffers|Cached/" /proc/meminfo'
检测内存压力:
bash复制vmstat 1 5 # 查看si/so(swap in/out)和内存列
问题1:free显示used很高但实际应用内存不多?
这通常是正常现象。Linux会利用空闲内存做缓存(buff/cache),这部分内存会在应用需要时快速释放。真正需要关注的是available值。
问题2:如何判断系统是否内存不足?
关键指标:
available接近0si/so(vmstat输出)频繁交换dmesg中出现OOM killer日志问题3:为什么/proc/meminfo和free的free值不同?
这是因为free命令的used计算方式不同(减去了buffers和cache)。真正的空闲内存应该看MemAvailable。
缓存优化:
/proc/sys/vm/dirty_ratio和dirty_background_ratio控制脏页比例vmtouch工具管理文件缓存swap调优:
swappiness(默认60):bash复制sysctl vm.swappiness=30
大页内存配置:
bash复制grep Huge /proc/meminfo
bash复制sysctl vm.nr_hugepages=1024
虽然/proc/meminfo和free是基础工具,但在生产环境中,我们还需要更强大的监控手段:
vmstat:提供系统级内存、swap、IO等综合指标
bash复制vmstat 1 # 每秒刷新
smem:按进程统计内存使用
bash复制smem -s rss -r # 按RSS排序
atop:高级交互式监控工具
bash复制atop -m # 内存监控模式
Prometheus+Granfa:搭建长期监控系统,采集node_memory_*指标
在实际运维中,我通常会结合多种工具:用free快速查看概况,用/proc/meminfo获取详细数据,用vmstat监控趋势,最后用专业监控系统做长期跟踪。这种分层方法既能快速响应问题,又能深入分析根本原因。