free命令不能定位内存泄漏,仅能发现异常占用现象;需结合slabinfo、pmap、valgrind等工具深入分析泄漏根源。

free 命令本身不能分析内存泄漏,只能发现异常占用现象
free 是一个快照式内存查看工具,它不追踪分配/释放行为,也不关联进程。你看到 used 高、available 低,或 buff/cache 持续上涨,只是「症状」,不是「病因」。真正定位泄漏必须配合其他工具——free 的作用是帮你决定「该不该深入查」以及「往哪个方向查」。
常见误导场景:
- 看到
buff/cache占用 80% 就以为系统“卡”或“出问题”,其实 Linux 会主动利用空闲内存做缓存,只要available不趋近于 0,通常无需干预 - 重启服务后
free看似恢复正常,但几小时后used又缓慢爬升 → 这才是泄漏的典型信号(需持续观察) -
free -h显示available仅剩 200MiB,但top里所有进程 RSS 总和才 1.2GiB → 很可能有内核模块、驱动、或未映射回用户态的 slab 分配在吃内存
用 free -w 实时监控 + 脚本记录趋势,比单次执行有用得多
手动敲 free -h 看一眼意义有限;关键是建立时间维度的观测。推荐用 free -w(带宽列)每 2 秒刷新,并配合简单日志记录:
while true; do
echo "$(date '+%F %T') $(free | awk 'NR==2{print $3,$7}')" >> /tmp/free_trend.log
sleep 2
done
之后用 awk 或 Excel 查看 used(第3列)和 available(第7列)是否呈现单向漂移:
Linux 安全审计工具,检查 SSH 配置、开放/监听端口、防火墙规则(ufw/iptables/nftables)、失败登录尝试、sudoers 权限...
- 如果
used线性增长、available线性下降,且与某个服务启停强相关 → 锁定该进程,准备用pmap或smaps_rollup深挖 - 如果
buff/cache涨得快但available不掉,大概率是文件读写密集型业务(如数据库预加载、日志归档),不是泄漏 - 注意区分
free -w中的buff(块设备缓冲)和cache(页缓存):前者长期不降可能指向底层存储驱动异常
当 free 显示 available 极低,优先排查 slab 和 kernel memory
用户态进程 RSS 总和远小于 used?很大概率是内核态内存没释放。此时别急着杀进程,先看:
- 运行
cat /proc/meminfo | grep -i "slab\|sreclaimable\|sunreclaim"—— 若SReclaimable很高但SUnreclaim持续上涨,说明 slab 分配器里有对象没被回收(常见于某些网络模块或自定义驱动) - 检查
slabtop(按c按缓存大小排序),重点关注# use高但Obj/kB异常低的 cache(例如kmalloc-192单个对象小但总量大,可能被高频小分配打满) - 某些内核版本中,
zram或zswap启用后也会让free显示失真(它们压缩内存但不计入常规used),可用cat /sys/block/zram0/mm_stat验证
free 发现异常后,下一步该用什么工具跟进
free 是路标,不是手术刀。确认异常后,按泄漏类型选工具:
- 用户态 C/C++ 程序:立刻上
valgrind --tool=memcheck --leak-check=full(开发环境),生产环境用gdbattach +info proc mappings+dump memory配合addr2line - Java 应用:不要只看
free,直接jstat -gc看老年代是否持续增长且 GC 不回收;再用jmap -histo:live找可疑对象实例数 - Docker 容器:
free在宿主机上看容易误判,应进容器执行free,并对比docker stats的mem usage / limit,同时检查/sys/fs/cgroup/memory/.../memory.stat中的total_inactive_file是否异常高(file-backed page leak) - 内核模块泄漏:
sudo cat /proc/slabinfo | awk '$3 > 10000 {print $1, $3}'找高频分配 cache,再结合modinfo和dmesg | tail -50看是否有 “out of memory” 或 “failed to allocate” 日志
最常被忽略的一点:很多“泄漏”其实是应用层缓存策略失控(比如自己实现的 LRU 没设上限),free 只告诉你内存被占了,但不会告诉你那是业务逻辑故意留的——得翻代码,而不是换工具。










