内核内存泄漏排查需按类型选用工具:先查/proc/slabinfo判断slab异常增长;显式泄漏用kmemleak;size失配用trace-cmd;引用计数问题则结合slabinfo与perf probe分析。

内核内存泄漏排查不能靠猜,得按泄漏类型选对工具和路径。显式分配不释放、引用计数错、slab缓存膨胀这三类问题,表现相似但根因不同,混用方法容易白忙。
先看 slab 是否异常增长
内核泄漏最直观的信号是 /proc/slabinfo 里某类缓存持续上涨。重点关注:
- size-4096、size-8192 等固定大小 slab —— 驱动或网络子系统常用,泄漏高发区
- SReclaimable 在 /proc/meminfo 中持续升高,但 SUnreclaim 不涨,说明缓存本可回收却滞留
- 用 slabtop -o 实时排序,看 OBJS 和 ACTIVE 列是否单边增长
用 kmemleak 快速抓显式泄漏
适用于 kmalloc/kmem_cache_alloc 分配后未 kfree/kmem_cache_free 的场景:
在无 root/sudo 权限的环境(云容器、VPS、隔离主机)中安装并配置 OpenClaw 浏览器工具的 headless Chrome。适用场景:...
- 确认内核已启用 CONFIG_DEBUG_KMEMLEAK=y,且 debugfs 已挂载:mount -t debugfs nodev /sys/kernel/debug/
- 触发扫描:echo scan > /sys/kernel/debug/kmemleak,稍等后读取:cat /sys/kernel/debug/kmemleak
- 输出中带完整调用栈的对象,基本就是泄漏源头;若只报地址无栈,需开 stack=on 并重启扫描
- 注意:kmemleak 对引用计数类泄漏(如 dentry、inode)不敏感,报“未引用”不等于真泄漏,要结合代码逻辑判断
用 trace-cmd 追踪特定 size 分配/释放失配
当 kmemleak 无结果,但 slab 某个 size 持续涨,就锁定该 size 做函数级追踪:
- 记录 kmalloc/kfree 调用,过滤指定大小:trace-cmd record -e kmalloc -f 'bytes_alloc==4096' -e kfree -T
- 运行几分钟后停止,导出分析:trace-cmd report | grep -E "(kmalloc|kfree).+ptr=0x"
- 对比 ptr 地址:有 kmalloc 没对应 kfree 的 ptr,就是泄漏点;再结合 -T 输出的栈,定位到驱动或子系统代码行
- 适合定位 cat、netdev、usb 等模块中固定 size 的分配遗漏
查引用计数与生命周期问题
这类泄漏增长慢、kmemleak 不报,但 /proc/slabinfo 中对象数稳定、pages 却涨,或 /proc/meminfo 的 Slab 总量缓慢爬升:
- 盯紧 dentry、inode、sock、nf_conntrack 等带 refcount 的 cache,用 cat /proc/slabinfo | grep -E "(dentry|inode|sock)"
- 对比不同时间点的 num_objs 和 num_slabs:前者不变后者涨,说明 slab 内碎片增多,可能是对象未被 put
- 结合 perf probe 或 systemtap 在关键函数(如 dput、iput、sock_put)插桩,统计 get/put 次数是否平衡
- 重点检查错误分支、goto 跳转、异步回调中漏掉的 put 操作
不复杂但容易忽略:别只盯着用户进程,内核模块、驱动、文件系统、网络协议栈才是泄漏重灾区。从 slab 异常出发,分类型选工具,比盲目开调试选项更高效。










