当前位置:首页>Linux>Linux内核SLUB调试之slabinfo工具

Linux内核SLUB调试之slabinfo工具

  • 2026-10-11 08:08:18
Linux内核SLUB调试之slabinfo工具

前面我们介绍了Linux内核SLUB调试功能,现在我们来介绍一下slabinfo等相关的工具,这对于理解并调试slab缓存功能很有帮助。

slabinfo介绍

slabinfo 不是普通系统命令,而是内核源码自带的官方调试工具。

它的源码位于内核源码树的tools/mm/slabinfo.c,由内核社区直接维护,数据直接取自内核 SLUB 分配器,精准度远高于第三方脚本,是排查内核内存问题的强大工具。

  1. 编译与一键部署

slabinfo 无需复杂配置,进入内核源码目录即可编译:

cd /path/to/linux-xxx/tools/mmmake

为了方便全局调用,建议做一个软链接:

sudo ln -s /path/to/linux-xxx/tools/vm/slabinfo /usr/bin/slabinfo
  1. 运行的三个前提

  1. 必须用 root 权限(涉及内核内存、sysfs 伪文件操作);

  2. 内核需开启CONFIG_SLUB_DEBUG=y(主流发行版内核默认已开启);

  3. 进阶调试功能,需内核启动参数添加slub_debug=xxx。

slabinfo字段解读

直接运行sudo slabinfo,看到的每一列都是 slab 缓存的核心数据,搞懂这些是排查的基础:

Name                   Objects Objsize           Space Slabs/Part/Cpu  O/S O %Fr %Ef FlgAcpi-Namespace             510      48           24.5K          1/0/5   85 0   0  99Acpi-Operand               952      72           69.6K         4/0/13   56 0   0  98Acpi-Parse                 949      56           53.2K         0/0/13   73 0   0  99Acpi-ParseExt              663      80           53.2K         0/0/13   51 0   0  99Acpi-State                 663      80           53.2K         0/0/13   51 0   0  99AF_VSOCK                   350    1224          458.7K         1/0/13   25 3   0  93 A...kmalloc-128               5856     128          749.5K       138/0/45   32 0   0 100kmalloc-16                6889      16          114.6K         5/3/23  256 0  10  96kmalloc-192               8253     192            1.6M      290/0/103   21 0   0  98kmalloc-1k                1852    1024            1.9M        28/4/31   32 3   6  98kmalloc-256               6769     256            1.8M      183/32/38   32 1  14  95kmalloc-2k                 998    2048            2.0M        30/5/34   16 3   7  97kmalloc-32                6512      32          208.8K        18/4/33  128 0   7  99
  • Name:slab 缓存名称(如 kmalloc-32);

  • Objects:当前已分配的对象数量;

  • Objsize:单个对象的大小(字节);

  • Space:该缓存占用的总内核内存;

  • Slabs/Part/Cpu:满 slab / 部分空闲 slab / 每 CPU 缓存 slab 数量;

  • O/S:每个 slab 包含的对象数;

  • O:页分配器阶数(2^order 为分配的页块大小);

  • %Fr:缓存空闲内存占比;

  • %Ef:内存使用效率;

  • Flg:slab 标志位(快速记忆:* 别名、dDMA、A 缓存对齐、P 中毒、Z 红区、F 完整性检查)。

slabinfo 核心参数

不用死记硬背所有参数,生产排查只需要掌握高频场景参数,随用随查:

  1. 查看完整 slab 列表

默认只显示有数据的 slab,空缓存会被隐藏:

  • slabinfo -e:仅显示空 slab;

  • slabinfo -z:显示所有 slab(空 + 非空)。

  1. 定位高内存占用(最常用)

排查内核内存上涨,第一步就是找 “内存大户”:

sudo slabinfo -S

-S会按总内存占用降序排列,自带人类可读单位,搭配head直接看 Top10 高占用缓存。

  1. 排查内存碎片

slab 采用 “最佳匹配” 分配,会产生内部碎片,-L参数按内存浪费量排序:

sudo slabinfo -L | head

比如申请 100 字节,内核会用 kmalloc-128 缓存,浪费 28 字节,这个参数能精准揪出碎片大户。

  1. OOM :不可回收 slab 筛选

很多生产 OOM 的元凶,是不可回收 slab 占满内存,-U参数就是为这个场景而生(内核 4.15 + 支持):

sudo slabinfo -U -S

这个参数源于一次真实生产故障:不可回收 slab 耗尽内存,OOM 杀手无进程可杀,直接宕机。排查 OOM 必用。

  1. 深度详情 + 正则筛选

想深挖某类缓存,用-r输出详细统计,支持正则匹配:

sudo slabinfo -r vm.*

开启 SLUB_DEBUG 后,还能看到分配 / 释放的代码来源,定位泄漏点事半功倍。

  1. 陌生缓存快速识别

遇到不认识的 slab 名,用-a查看别名,直接知道它缓存哪种内核对象:

sudo slabinfo -a
  1. 全局汇总统计

  • slabinfo -T:极简汇总,看 slab 总数量、总内存;

  • slabinfo -X:扩展统计,适合做系统内存诊断报告。

进阶调试:slabinfo 搞定内存损坏

slabinfo 不止能看统计,还能直接做slab 内存调试,专门解决内存越界、双重释放、内存损坏等硬核问题。

  1. 先开启内核调试参数

在 GRUB 启动参数中添加:

slub_debug=FZPU
  • F:开启 slab 完整性检查;

  • Z:添加内存红区,防越界;

  • P:slab 中毒,释放后填充毒页;

  • U:追踪用户态关联 slab。

  1. 动态调试:-d 参数

无需重启,直接通过 slabinfo 开启 / 关闭调试:

sudo slabinfo --debug=FZPU  # 开启调试sudo slabinfo -d            # 关闭调试

底层通过操作/sys/kernel/slab/<缓存名>/伪文件实现,安全无侵入。

  1. 内存校验:-v 参数

怀疑内核 slab 内存损坏?用-v做完整性校验:

sudo slabinfo -v

内核会遍历所有 slab 对象,检查元数据有效性,结果输出到内核日志,可以准确查出内存损坏问题。

其他配套工具:slabtop & slabratetop

除了 slabinfo,这两个实时工具能 complement 排查能力:

  1. slabtop:类 top 实时监控

和系统 top 一样,实时刷新 slab 占用状态,默认按对象数排序:

sudo slabtop

适合实时观察 slab 变化,快速定位高频分配缓存。

  1. slabratetop(eBPF):实时分配速率

这是 eBPF 时代的新利器,直接追踪内核 slab 分配速率:

sudo slabratetop-bpfcc 5 3

5 秒刷新一次,显示 3 次,底层追踪kmem_cache_alloc,精准看内核态分配速度和字节数,比传统工具更灵敏。

操作实例:谁在吃掉内核 slab 内存?

下面用一个真实排障流程,教你定位内核态内存占用元凶。

场景

服务器内核 slab 内存持续上涨,用户态进程无异常,系统负载缓慢升高。

步骤 1:定位高消耗缓存

用slabratetop找到分配最频繁的缓存:

sudo slabratetop-bpfcc

输出显示:vm_area_struct缓存每秒分配 176 次,字节数居高不下。

步骤 2:追踪内核调用栈

用 kprobe 抓取分配内核栈:

sudo kprobe-perf -s 'p:kmem_cache_alloc name=+0(+96(%di)):string' | grep -A10 "vm_area_struct"

结果

清晰看到调用链:sys_brk() → do_brk() → do_brk_flags() → vm_area_alloc() → kmem_cache_alloc()

根因:进程频繁调用brk()扩张内存,内核持续分配 VMA 结构体,导致 slab 内存上涨。针对性优化进程内存管理策略后,问题解决。

slab 内存清零防护

最后补一个生产安全配置,防止 slab 内存数据泄露:在内核启动参数中添加:

init_on_alloc=1 init_on_free=1

slab 对象分配 / 释放时自动清零,提升内核安全性,仅带来轻微性能损耗,安全敏感型业务建议开启。

最新文章

随机文章