内存与 OOM58 条

slabtop 内核缓存观测

按占用排序展示 slab 对象缓存(dentry、inode 等),是定位内核态内存增长来源的常用起点。

什么是 slabtop

内核为常用对象(目录项 dentry、索引节点 inode、网络连接结构等)维护对象缓存池,统称 slab。slabtop 按占用大小排序展示这些缓存,帮助判断内核态内存去哪了。它不能直接区分“正常缓存”与“内存泄漏”,必须通过多次采样对比同一缓存项的增长;同时要区分 SReclaimable(可回收)与不可回收部分,前者增长通常只是文件缓存行为。

基本信息

软件包procps-ng(提供 slabtop)
排序slabtop -s c 按缓存大小排序
一次性输出slabtop -o(适合脚本采集)
其他排序-s a 活跃对象、-s u 使用率
原始数据/proc/slabinfo
汇总视图grep -E 'Slab|SReclaimable' /proc/meminfo

典型使用场景

  • 内核态内存持续增长:找出是哪一个缓存项在涨
  • 容器宿主排查:区分租户容器与内核缓存各自的占用
  • inode 与 dentry 缓存评估:判断文件数量带来的内存开销
  • 与 meminfo 的 Slab 字段交叉验证,确认口径一致
  • 常规巡检:记录基线,便于事后对比

常用命令

常用命令
sudo slabtop -o -s c | head -20          # 一次性输出,按缓存大小排序
sudo slabtop -s c                        # 交互式观察
sudo slabtop -o -s a | head -15          # 按活跃对象排序
grep -E '^(Slab|SReclaimable|SUnreclaim)' /proc/meminfo
head -5 /proc/slabinfo                   # 原始数据(字段含义见内核文档)
# 间隔采样对比增长项:
sudo slabtop -o -s c | head -8 > /tmp/slab1; sleep 60; sudo slabtop -o -s c | head -8 > /tmp/slab2; diff /tmp/slab1 /tmp/slab2

输出与汇总字段

字段含义判读要点
OBJS该缓存对象数量随文件或连接数增长属正常
SIZE单个对象大小不同内核差异较大
CACHE SIZE该缓存总占用排序的主依据
SReclaimable可回收 slab 总量增长常与文件缓存相关
SUnreclaim不可回收 slab持续增长要重点排查
dentry 与 inode 缓存随文件访问量增长是设计行为,只要处在可回收范围就无需干预;把它们当作内存泄漏去处理是本末倒置。
直接改 /proc/sys/vm/drop_caches 只能临时回收部分 slab,不解决 SUnreclaim 持续增长:后者通常意味着内核或驱动层面的问题,需要进一步定位。
常规做法是每天把 slab 排名前几项记录下来当基线:等内存告警出现时直接对比,就能看出是哪一类缓存发生了变化,而不是从头开始排查。

易错点

  • 单次快照无法区分缓存与泄漏,要间隔采样看增长项,否则容易误判
  • 可回收 slab(SReclaimable)增长优先怀疑文件缓存而非泄漏,处理方向不同
  • 把 dentry/inode 缓存当异常去清理,业务流量一大就会重新涨回,等于白做
  • 忽略不可回收部分(SUnreclaim)的持续增长:这往往是真正需要升级内核或驱动修复的线索

数据来源与参考

  • procps-ng 文档 slabtop(1)
  • Linux 内核 Documentation/filesystems/proc.rst
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌