如何使用 slabtop 分析 Linux 内核缓存占用过高的问题?

文章导读
当 Linux 系统可用内存偏低但用户态进程占用正常时,推荐使用 slabtop 查看内核 slab 分配器缓存,重点排查 dentry、inode 或特定驱动缓存是否异常增长。
📋 目录
  1. A 命令速用版
  2. B 原理简述
  3. C 分步处理
  4. D 怎么验证是否生效
  5. E 常见坑
  6. F 参考资料
A A

当 Linux 系统可用内存偏低但用户态进程占用正常时,推荐使用 slabtop 查看内核 slab 分配器缓存,重点排查 dentry、inode 或特定驱动缓存是否异常增长。

先说结论:slabtop 是定位内核态内存占用的首选工具,适合排查“内存被吃光但找不到进程”的场景,但需注意区分正常缓存与内存泄漏。

  • 先定位:结合 free 与 /proc/meminfo 确认 Slab 占用比例,再用 slabtop 找出占用最高的缓存名称。
  • 先做:关注 /proc/meminfo 中的 SUnreclaim 指标,判断不可回收内存是否异常增长,避免误杀正常业务缓存。
  • 再验证:观察特定缓存对象数变化或重启相关服务后内存是否回落,确认是否存在泄漏。

命令速用版

以下命令需 root 权限执行,用于快速查看内核缓存状态:

slabtop                      # 进入交互界面,默认按活跃对象数排序
slabtop -o                   # 输出一次后退出,适合脚本或截图
slabtop -s c                 # 按缓存总大小(CACHE SIZE)降序排列
slabtop -d 5                 # 设置刷新间隔为 5 秒

若需查看原始数据以便脚本分析,可直接读取:

cat /proc/slabinfo

原理简述

Linux 内核为了提升小对象内存分配效率,使用了 Slab 分配器机制。它会将常用对象(如进程描述符、目录项 inode、目录缓存 dentry 等)预先分配并缓存起来。当系统频繁创建删除文件、网络连接或进程时,这些缓存会迅速增长。

正常情况下,内存压力增大时内核会回收部分 Slab 缓存。但如果某些对象被标记为“不可回收”(unreclaimable),或者驱动程序申请后未释放,就会导致 slab_unreclaimable 持续升高,表现为系统空闲内存减少,但 top 命令中用户进程内存占用却不高。

分步处理

1. 确认 Slab 内存占用情况

首先查看系统整体内存分布,确认 Slab 是否确实占用过高。执行:

cat /proc/meminfo | grep -E "MemTotal|Slab|SUnreclaim"

关注 Slab 总值及 SUnreclaim(不可回收部分)。虽然没有绝对的百分比阈值,但若 SUnreclaim 占总内存比例较高且持续上升,需进一步排查。

2. 找出占用最高的缓存

如何使用 slabtop 分析 Linux 内核缓存占用过高的问题?

运行 slabtop 并按缓存大小排序:

slabtop -s c

记录 CACHE SIZE 列数值最大且 OBJ 利用率异常(如过低或持续 100%)的缓存名称(NAME 列),常见的高占用项包括 dentry、inode_cache、buffer_head 或 kmalloc-*

3. 判断缓存是否可回收

标准内核中不存在统一的 reclaim_account 文件供用户直接查询。实践中可通过以下特征辅助判断:

  • 看名称:dentry、inode_cache 等通用缓存通常可回收;特定驱动名命名的缓存(如 ext4_inode_cache 以外的私有缓存)若持续增长需警惕。
  • 看指标:若 /proc/meminfo 中 Slab 很高但 SUnreclaim 很低,说明大部分是可回收缓存,风险较低;若 SUnreclaim 同步高涨,则泄漏风险高。
  • 看趋势:在业务低峰期观察 slabtop,若特定缓存对象数(OBJS)只增不减,可能存在泄漏。

4. 深入分析泄漏源

若确认为不可回收内存泄漏,需结合业务场景排查。例如 dentry 过高可能涉及大量小文件操作或 NFS 挂载异常;kmalloc-*过高可能关联特定内核模块。可使用 perf 或 crash 工具进行内核态追踪,但这需要较高的内核调试经验。

怎么验证是否生效

1. 观察内存指标回落

在测试环境中,可尝试清理缓存后观察内存变化(生产环境慎用):

如何使用 slabtop 分析 Linux 内核缓存占用过高的问题?
echo 2 > /proc/sys/vm/drop_caches

执行后再次查看 /proc/meminfo 中的 Slab 和 SUnreclaim 数值,若明显下降且业务恢复正常,说明是缓存堆积;若数值很快回升且不下降,可能存在泄漏。

2. 监控稳定性

修复疑似问题(如重启异常服务、调整内核参数)后,持续运行 slabtop -o 配合定时任务记录快照,观察特定缓存的增长趋势是否趋于平稳。

常见坑

1. 权限不足

slabtop 需要 root 权限才能读取完整的内核数据,普通用户运行可能看不到详细信息或报错。

2. 误清理生产缓存

drop_caches 会强制释放页面缓存和 dentry/inodes,可能导致瞬间 I/O 升高或业务抖动,仅建议在测试环境或维护窗口期使用。

3. 混淆缓存与泄漏

Slab 占用高不一定是泄漏,内核会利用空闲内存做缓存以提升性能。只有当 SUnreclaim 持续增长且伴随可用内存耗尽时,才优先怀疑泄漏。

参考资料

  • 建议查阅官方文档:man slabtop
  • Linux 内核文档:Documentation/vm/slab.rst (视内核版本而定)
  • 相关技术社区关于 slab_unreclaimable 的排查案例