首页/系统/Linux 内核与性能调优速查/slab 增长与内核泄漏排查
内存与 OOM58 条

slab 增长与内核泄漏排查

定位内核对象泄漏:slabtop 找持续增长缓存 → 读 /sys/kernel/slab/<cache>/ 的 objects → 必要时启用 kmemleak 扫描。

怎么定位

内核对象(slab)泄漏的排查路径是:先用 slabtop 找到持续增长的缓存,再读 /sys/kernel/slab/<cache>/objects 确认对象数是否单调上升,必要时借助 kmemleak 定位未释放的分配点。关键在于先区分可回收与不可回收——SReclaimable 部分在内存压力下会被释放,只有 SUnreclaim 或具体缓存的对象数持续增长,才构成泄漏的有力证据。

基本信息

总览sudo slabtop -o -s c(按缓存占用排序)
单缓存对象数/sys/kernel/slab/<cache>/objects
总量与构成/proc/meminfo 的 Slab、SReclaimable、SUnreclaim
深度扫描kmemleak(需内核编译支持),报告在 /sys/kernel/debug/kmemleak
权限多数接口需 root
容器环境命名空间受限,需在宿主侧排查

典型使用场景

  • 内存缓慢增长而进程 RSS 解释不了,转向内核侧取证
  • 网络或存储负载长期运行后 dentry/inode 等缓存异常膨胀
  • 容器频繁创建销毁后残留对象(cgroup、netns 相关缓存)增多
  • 长时间运行的服务器定期核对 slab 总量作为健康检查项
  • 为内核或驱动问题提供可复现的量化证据

排查步骤

排查步骤
sudo slabtop -o -s c | head -10  # 按占用大小排序,锁定可疑缓存
cat /sys/kernel/slab/dentry/objects  # 单缓存对象数,间隔采样看是否单调增长
awk '/^(Slab|SReclaimable|SUnreclaim)/{print}' /proc/meminfo  # 内核对象总量与可回收比例
mount | grep -q debugfs || sudo mount -t debugfs none /sys/kernel/debug  # kmemleak 报告需要 debugfs
sudo cat /sys/kernel/debug/kmemleak 2>/dev/null | head  # 需要内核开启 kmemleak 才有内容
echo scan | sudo tee /sys/kernel/debug/kmemleak  # 触发一次扫描(有性能开销,慎用)

指标读法

指标含义判读要点
Slab内核对象总占用作为总量基线
SReclaimable压力下可释放的部分增长本身不算泄漏
SUnreclaim不可回收部分持续增长是泄漏的主要嫌疑
objects单个缓存的对象数量间隔采样对比趋势,单调增长即异常
slabtop 排序各缓存占用对比用于快速缩小候选范围
kmemleak 需要内核编译时开启并启用,运行时触发扫描会产生明显性能开销,生产环境应谨慎。它报告的是「疑似无法到达的内存」,仍需结合业务代码与复现路径确认。
slab 增长也可能来自正常业务变化:连接数、文件数、容器数增加都会带动对应缓存。判断泄漏要同时满足两点——对象数持续单调增长,且与业务量变化不匹配、负载回落后仍不释放。

易错点

  • 把正常缓存增长当泄漏:先确认对象数与业务量的相关性以及是否会在负载下降后释放
  • 只盯 SReclaimable:可回收部分不是泄漏证据,应关注 SUnreclaim 与单缓存对象数
  • 在生产随意启用 kmemleak:扫描开销可能影响业务,应先在测试环境验证
  • 忽略缓存名称的版本差异:不同内核版本的对象层次与统计接口会变化,排查方法需要相应调整
  • 在容器内排查宿主 slab:命名空间限制导致看不全,应到宿主侧取证

数据来源与参考

  • Linux 内核 Documentation/dev-tools/kmemleak.rst
  • Linux 内核 /sys/kernel/slab 接口
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌