当前位置:首页>Linux>Linux free 命令全解:内存指标、内核数据源、底层函数与内存优化

Linux free 命令全解:内存指标、内核数据源、底层函数与内存优化

  • 2026-09-15 22:33:36
Linux free 命令全解:内存指标、内核数据源、底层函数与内存优化
Hello,大家好,我是程序媛MM。

本文约2600字,今天继续来学习内存分析相关的知识。

关注公众号, 即可获得与Linux相关的电子书籍以及常用开发工具,文末有文档清单。

💡 本文基于在我正在维护的产品上面输出的样例讲解:

             total         used         free       shared      buffersMem:        194576       160808        33768        46192         6552-/+ buffers:             154256        40320Swap:            0            0            0

默认单位:KB

前言

free 命令是 Linux 运维、嵌入式开发、实时系统调试中最核心的内存排查工具。绝大多数人仅会看懂基础数值,却不了解指标内核来源、内存分类本质,常出现"空闲内存很低但系统正常""缓存占用高不敢清理""shared 内存泄漏无法释放"等问题。

本文结合内核源码、proc 文件机制、内存分级逻辑,全面解析 free 命令指标含义、底层数据源、核心内核函数、内存泄漏排查、全场景优化方案。


一 free 输出字段逐行深度解析

1 Mem 物理内存原始统计行

该行是内核原始内存统计,包含所有内存占用,无法直接判断业务内存压力,各字段释义如下:

字段
含义
内核对应
total
系统可用总物理内存,已扣除 BIOS、内核镜像、预留内存
MemTotal
used
广义已用内存,计算公式:总内存-空闲内存,包含进程内存、共享内存、缓冲缓存等所有占用
—
free
完全空闲、无任何数据、可直接分配的裸物理内存
MemFree
shared
⚠️ 核心易混淆字段,包含 POSIX 共享内存(/dev/shm)、System V 共享内存、tmpfs 临时文件、进程匿名共享映射,无法被 drop_caches 自动回收
Shmem
buffers
块设备缓冲,用于裸磁盘、块 IO 读写的临时缓存,主要存储扇区级原始数据
Buffers

2 -/+ buffers 真实内存行

这是判断系统内存压力的唯一标准,剥离了可回收的系统缓冲,还原业务真实内存占用:

-/+ buffers:             154256        40320
  • used(154256):业务进程真实占用内存,剔除可回收 buffers/cache
  • free(40320):系统真实可用内存 = 空闲裸内存 + 可快速回收的缓冲缓存

核心逻辑:Linux 会最大化利用空闲内存做 IO 缓冲提升性能,缓冲内存不属于真正占用,可随时回收给业务进程。

3 Swap 交换分区行

样例中 Swap 全为 0,代表系统未配置交换分区。实时 Linux(PREEMPT_RT/Xenomai)强制建议禁用 Swap,磁盘换页会带来毫秒级延迟,彻底破坏系统实时性与确定性。


二 buffers 与 Cache 核心区别

类型
面向对象
缓存内容
典型场景
Buffers 块缓冲
裸块设备
磁盘扇区原始数据
dd、裸盘读写、文件系统元数据缓存
Page Cache 页缓存
文件系统
业务读写的普通文件、程序二进制、日志文件
提升文件读写速度的核心机制
Shmem 共享内存
进程间通信
匿名共享内存、tmpfs 文件
⚠️ 属于持久化匿名占用,内核不会自动回收,内存泄漏高发点

三 free 命令数据源与内核底层原理

1 上层数据来源

free 属于 procps 工具集,无硬件读取逻辑,所有数据均来自内核虚拟文件 /proc/meminfo。

执行链路:

free 命令 → 解析 /proc/meminfo 文本 → 通过固定公式计算 → 输出各字段

2 核心内核函数(内核源码层级)

内核通过固定函数实时统计内存状态、生成 meminfo 文件:

函数
作用
meminfo_proc_show()核心入口函数
,汇总所有内存、缓存、共享内存、Swap 统计数据,格式化输出 /proc/meminfo
si_meminfo()
统计基础内存指标,包括 MemTotal、MemFree、Buffers、Cached
si_swapinfo()
统计交换分区总容量、已用、空闲数据
global_page_state()
统计系统页状态,区分空闲页、缓存页、匿名页、共享页
calculate_available_memory()
内核 4.14+ 新增,精准计算真实可用内存,剔除不可回收内存

3 核心计算公式

# 原始 used原始 used = MemTotal - MemFree# 真实业务已用(-/+ buffers 行的 used)真实业务已用 = 原始 used - Buffers - Cache# 真实可用内存(-/+ buffers 行的 free)真实可用内存 = MemFree + Buffers + Cache - 不可回收 Slab/Shmem

四 各类内存手动释放方式(含 Shared 精简方案)

1 普通 Cache/Buffers 释放(通用方案)

普通文件缓存、块缓冲可通过内核接口手动回收,生产仅用于调试排查,不建议频繁执行:

# 先刷写脏数据防止丢数据,再释放对应缓存sync && echo 1 > /proc/sys/vm/drop_caches  # 释放页缓存sync && echo 2 > /proc/sys/vm/drop_caches  # 释放目录、inode 缓存sync && echo 3 > /proc/sys/vm/drop_caches  # 释放全部可回收缓存

2 Shared(Shmem) 共享内存释放(精简实操)

⚠️ 关键结论:drop_caches无法释放 Shmem,共享内存、tmpfs 占用需针对性清理。

核心场景操作:

1. 排查占用

ipcs -m              # 查看 System V 共享内存df -h /dev/shm       # 查看 POSIX 共享内存占用

2. 清理 System V 共享内存(进程崩溃残留泄漏)

# 单个清理ipcrm -m 共享段ID# 批量清理ipcs -m | awk 'NR>3 {print $2}' | xargs -r ipcrm -m

3. 清理 /dev/shm 僵尸文件

# 清理 JVM、程序异常退出残留文件find /dev/shm -name "hsperfdata_*" -delete

4. 彻底释放

  • 核心依赖业务进程正常退出,执行 munmap、shm_unlink 释放映射
  • 紧急场景可终止持有共享内存的进程

⚠️ RT 实时系统严禁暴力删除 /dev/shm 文件,会引发调度抖动、实时延迟飙升。


五 Linux 内存压力排查流程

1 核心判断标准

  • ✅ 不看原始 free 值,只看 -/+ buffers 行的 free 值
  • 🚨 若出现以下情况,说明内存压力过载:
    • 真实可用内存持续偏低
    • 出现 Swap 占用
    • dmesg 报 OOM-killer

2 分层定位内存占用

排查对象
工具/命令
说明
进程级内存top
、htop 查看 RSS;ps aux --sort -rss
排序定位大内存进程
内核 Slab 内存slabtop
查看可回收/不可回收内核缓存
共享内存ipcs
、/dev/shm 磁盘占用
排查共享内存泄漏
实时系统专项
监控内存碎片化、mlock 锁定内存、大页占用
保障实时性

六 全场景内存优化方案

1 内核 VM 参数调优(永久生效)

# 1. 实时系统核心:禁用交换分区,关闭换页vm.swappiness=0# 2. 脏页刷写优化,避免 IO 瞬时夯机vm.dirty_background_ratio=5vm.dirty_ratio=15vm.dirty_expire_centisecs=3000# 3. 缓存回收策略,优先回收文件缓存vm.vfs_cache_pressure=100# 4. 预留空闲内存,缓解内存碎片vm.min_free_kbytes=8192

2 应用层优化

  • IO 密集程序:使用 O_DIRECT 绕过页缓存,避免缓存内存暴涨
  • 常规业务:修复内存泄漏,常驻服务定期巡检 RSS 占用
  • 共享内存管控:规范程序退出逻辑,主动释放 shm 资源,避免残留泄漏

3 实时 Linux专项优化

优化项
操作
禁用 Swap
永久关闭,杜绝换页延迟抖动
大页管理
关闭透明大页,开启固定大页,减少缺页中断
内存锁定
业务进程使用 mlockall 锁定内存,禁止换出
内核裁剪
裁剪冗余驱动、文件系统,减少内核常驻内存占用
Shmem 限制
限制 /dev/shm 最大容量,防止无上限暴涨

七 高频误区总结

误区
真相
❌ free 列数值低 = 内存不足
✅ Linux 默认缓存所有空闲内存,以真实可用内存为准
❌ echo 3 可以释放所有内存
✅ 仅释放普通缓存,对 Shmem 共享内存无效
❌ 进程退出自动释放所有共享内存
✅ System V 共享内存随内核生命周期,进程崩溃会永久残留
❌ 实时系统可开启 Swap
✅ 致命错误,彻底破坏实时确定性

八 全文总结

  1. free 命令数据全部来源于 /proc/meminfo,由内核内存管理模块统一统计,核心函数为 meminfo_proc_show()

  2. 排查内存压力的核心是 -/+ buffers 行指标,切勿通过原始 free、used 数值判断系统状态

  3. 普通缓存可自动/手动回收,Shmem 共享内存为特殊内存,需单独清理、重点防控泄漏

  4. 通用 Linux 侧重 IO 缓存优化,实时 Linux 核心是禁用 Swap、锁定内存、消除碎片、杜绝抖动,保障系统实时性


往期文章(欢迎订阅技术分享栏目全部文章):

【项目实战】Linux 下 OTA 升级系统成砖问题排查与解决 (第一次遇见的现象,不要错过)
【项目实战】SPI Nor Flash下OTA升级概率失败导致系统成砖问题的排查和解决方法
Linux文件读写原理、分片策略、异常处理及 OTA 低内存落地实践
【Linux面试题】: 在做OTA升级时双分区切换时你所做的可靠性保障措施有哪些?

“谢谢你看到这里”

这里是女程序员的笔记本

 15年+嵌入式软件工程师兼二胎宝妈

分享读书心得、工作经验,自我成长和生活方式。

希望我的文字能对你有所帮助

最新文章

随机文章