云计算百科
云计算领域专业知识百科平台

Linux命令-slabtop(实时显示内核 slab 缓存信息)

Linux命令-slabtop(实时显示内核 slab 缓存信息)

    • 🔰 简介
    • 📖 语法
    • ⚙️ 选项
    • 💡 实战示例
      • 示例 1:基本 slabtop
      • 示例 2:按对象数排序
      • 示例 3:一次性输出 + 监控
      • 示例 4:诊断内核内存泄漏
      • 示例 5:常见 cache 名称识别
      • 示例 6:与用户态内存工具对比
      • 示例 7:性能调优场景
      • 示例 8:自动化分析与脚本
    • ⚠️ 注意事项
    • 📝 总结
    • 📚 相关命令

快速参考 slabtop 是 实时显示 Linux 内核 slab 分配器缓存使用情况的工具,类似 top 但专门针对内核态内存(slab / slub / slob 三种分配器之一)。它显示各种内核对象的缓存命中率、对象数、占用内存,是诊断内核内存泄漏、内存碎片、驱动 bug 的核心工具。用户态 top 看进程内存,slabtop 看内核内存。


🔰 简介

项目说明
命令全称 slab top
所属包 procps-ng
数据源 /proc/slabinfo
工作模式 实时刷新(默认 3 秒),或一次性输出
用途 诊断内核态内存问题
权限 需要 root(部分内核版本普通用户可见但不全)
现代替代 slabtop(命令本身)cat /proc/slabinfo(原始数据)perf / bpftool(高级诊断)

slab / slub / slob 三种分配器:

分配器特点用途
slab 原始实现,复杂 早期内核
slub 简化版,Linux 默认 大多数发行版
slob 极简版(Simple List of Blocks) 嵌入式、小内存

slab 是什么:

  • Linux 内核的小对象内存分配器(替代频繁的 kmalloc/kfree)
  • 预先为常见对象(task_struct、inode、dentry、buffer_head 等)建立对象池(cache)
  • 申请对象时从 cache 取,避免反复创建/销毁
  • 解决内存碎片问题

📖 语法

slabtop [选项]


⚙️ 选项

选项简写说明
–delay=N -d N 刷新间隔(秒),默认 3
–sort=SORT -s SORT 排序字段(见下表)
–once -o 一次性输出(不刷新)
–version -V 版本
–help -? 帮助

排序字段(-s 可选):

字段含义
a ACTIVE 对象数
b 对象数/页(OBJ/SLAB)
c 缓存大小(CACHE SIZE)
l 命中次数(HITS)
n 名称(NAME)
o 活跃对象数 × 对象大小(活跃内存)
p 每页对象数 / 每 slab
s 对象大小(OBJ SIZE)
u 缓存使用率

💡 实战示例

示例 1:基本 slabtop

# 实时刷新(默认 3 秒)
$ sudo slabtop

Active / Total Objects (% used) : 678901 / 1234567 (55.0%)
Active / Total Slabs (% used) : 23456 / 34567 (67.9%)
Active / Total Caches (% used) : 98 / 142 (69.0%)
Total / Used Memory : 256789 / 145678

OBJS ACTIVE USE OBJ SIZE SLABS OBJ/SLAB CACHE SIZE NAME
45678 34567 75% 0.50K 1234 37 49360K task_struct
12345 10987 89% 0.13K 412 30 16480K dentry
12345 10000 81% 0.06K 200 62 16000K kmalloc-64
9876 7890 80% 1.00K 2465 4 39440K inode
8765 7000 79% 0.25K 567 15 22680K kmalloc-256
...

字段详解:

字段含义
OBJS 该 cache 中总对象数
ACTIVE 正在使用的对象数
USE 使用率(ACTIVE/OBJS %)
OBJ SIZE 单对象大小
SLABS 分配的 slab 页数
OBJ/SLAB 每个 slab 含多少对象
CACHE SIZE 该 cache 占用的总内存
NAME cache 名(task_struct 等)

头部统计:

行含义
Active / Total Objects 活跃对象 / 总对象
Active / Total Slabs 活跃 slab / 总 slab
Active / Total Caches 活跃 cache / 总 cache
Total / Used Memory 内存总量 / 使用量

示例 2:按对象数排序

# 按 OBJS 排序(看哪个 cache 对象最多)
$ sudo slabtop -s a

# 按 CACHE SIZE 排序(看哪个 cache 占内存最多)
$ sudo slabtop -s c

# 按 NAME 排序
$ sudo slabtop -s n

# 按对象大小排序
$ sudo slabtop -s s

# 实战:找出最大 cache
$ sudo slabtop -s c -o | head -20
Active / Total Objects (% used) : 678901 / 1234567 (55.0%)
...
OBJS ACTIVE USE OBJ SIZE SLABS OBJ/SLAB CACHE SIZE NAME
1024000 800000 78% 0.50K 32768 32 4096000K dentry
500000 400000 80% 1.00K 12500 40 2000000K inode
200000 150000 75% 0.25K 2000 100 1600000K kmalloc-256
...
# 重点关注:CACHE SIZE 大的 = 占用内存多

示例 3:一次性输出 + 监控

# 一次性输出(不刷新)
$ sudo slabtop -o
# 适合脚本处理

# 监控 5 秒输出
$ sudo slabtop -d 1 -o
# 每秒刷新一次

# 录制到文件做趋势分析
$ sudo slabtop -d 5 -o >> /var/log/slab.log &
# 持续 5 秒间隔输出

# 配合 grep
$ sudo slabtop -o | grep -E "dentry|inode|task_struct"
OBJS ACTIVE USE OBJ SIZE SLABS OBJ/SLAB CACHE SIZE NAME
45678 34567 75% 0.50K 1234 37 49360K task_struct
12345 10987 89% 0.13K 412 30 16480K dentry
9876 7890 80% 1.00K 2465 4 39440K inode

示例 4:诊断内核内存泄漏

# 场景:系统内存持续增长,怀疑内核泄漏

# 1. 第一次记录
$ sudo slabtop -o > /tmp/slab_1.txt
$ date
2024-01-15 14:30:00

# 2. 等待 5 分钟
$ sleep 300

# 3. 第二次记录
$ sudo slabtop -o > /tmp/slab_2.txt
$ date
2024-01-15 14:35:00

# 4. 对比
$ diff /tmp/slab_1.txt /tmp/slab_2.txt
# 找出增长最快的 cache
# 例如:dentry 数量持续增长 = 文件系统相关驱动有问题
# 例如:nf_conntrack 持续增长 = 防火墙连接表泄漏
# 例如:vm_area_struct 持续增长 = 进程内存映射泄漏

# 5. 实战:自动化监控
$ cat /opt/scripts/slab_monitor.sh
#!/bin/bash
LOG=/var/log/slab_growth.log
THRESHOLD=10000 # 5 分钟增长阈值

prev_count=0
prev_name=""

while true; do
# 取 cache 中最大 5 个
output=$(slabtop -o | head -7 | tail -5)
# 提取最大 cache
max=$(echo "$output" | tail -1)
name=$(echo "$max" | awk '{print $NF}')
objs=$(echo "$max" | awk '{print $1}')

# 检测增长
if [ "$name" = "$prev_name" ] && [ $((objs prev_count)) -gt $THRESHOLD ]; then
echo "[$(date)] 警告: $name 增长 $((objs prev_count)) 个对象" >> $LOG
logger -p kern.warning "Slab cache $name growing: $objs"
fi

prev_name=$name
prev_count=$objs
sleep 300
done

示例 5:常见 cache 名称识别

# ========== 1. 进程相关 ==========
$ sudo slabtop -o | grep -E "task_struct|signal|files_struct"
# task_struct: 进程描述符(每个进程 1 个)
# signal_struct: 信号结构
# files_struct: 进程打开的文件

# ========== 2. 文件系统相关 ==========
$ sudo slabtop -o | grep -E "dentry|inode|buffer_head"
# dentry: 目录项(**最常见大对象**)
# inode: 文件元数据
# buffer_head: 文件页缓存

# ========== 3. 网络相关 ==========
$ sudo slabtop -o | grep -E "sk_buff|sock|nf_conn"
# sk_buff: 网络数据包(**网络性能关键**)
# sock: 套接字
# nf_conn: netfilter 连接追踪

# ========== 4. 内存管理 ==========
$ sudo slabtop -o | grep -E "vm_area|page|mm_struct"
# vm_area_struct: 进程的虚拟内存区
# page: 内核页帧描述符

# ========== 5. 驱动相关 ==========
$ sudo slabtop -o | grep -E "scsi|usb|kvm"
# 各类驱动对象

# ========== 实战:dentry 增长 = 目录项泄漏 ==========
$ sudo slabtop -s c -o | head -10
OBJS ACTIVE USE OBJ SIZE SLABS OBJ/SLAB CACHE SIZE NAME
1024000 800000 78% 0.13K 32768 32 4096K dentry
# 如果持续增长:
# 1. 检查是否有进程持续打开/关闭目录
# 2. 检查 NFS / FUSE 挂载
# 3. 同步检查 /proc/sys/fs/dentry-state
$ cat /proc/sys/fs/dentry-state
134567 109876 45 0 0 0
# nr_dentry / nr_unused / age_limit / …

# 手动清理
$ echo 2 > /proc/sys/vm/drop_caches
# 释放 dentry + inode cache

示例 6:与用户态内存工具对比

# ========== 1. 用户态 vs 内核态 ==========

# 用户态:top / ps
$ top
# 字段:VIRT(虚拟)/ RES(实际)/ SHR(共享)
# 这些是**进程**的用户态内存

# 内核态:slabtop
$ sudo slabtop
# 字段:OBJS / SLABS / CACHE SIZE
# 这些是**内核对象**的内存

# ========== 2. 完整内存视图 ==========

# 总览
$ free -h
total used free shared buff/cache available
Mem: 7.7G 1.2G 4.0G 100M 2.5G 6.0G
# total = 物理 RAM
# used = 已用(用户 + 内核 + 缓存)
# buff/cache = 内核页缓存(**会自动回收**)
# available = **真正可用**(含可回收缓存)

# 内核 slab 占多少?
$ sudo slabtop -o | head -1
Active / Total Objects (% used) : 678901 / 1234567 (55.0%)
Total / Used Memory : 256789 / 145678
# Used Memory = 内核 slab 占用的内存

# 用户态 + 内核态 = 完整内存占用

# ========== 3. /proc/meminfo 详细信息 ==========
$ grep -E "Slab|SReclaimable|SUnreclaim" /proc/meminfo
Slab: 145678 kB
SReclaimable: 87654 kB ← 可回收的 slab
SUnreclaim: 58024 kB ← 不可回收的 slab
# SReclaimable + SUnreclaim = Slab

# ========== 4. 完整内存全景图 ==========
$ cat /proc/meminfo | head -30
MemTotal: 8057892 kB
MemFree: 4123456 kB
MemAvailable: 6234567 kB
Buffers: 123456 kB
Cached: 2098765 kB
SwapCached: 0 kB
Active: 1234567 kB
Inactive: 1876543 kB
Active(anon): 456789 kB
Inactive(anon): 123456 kB
Active(file): 777778 kB
Inactive(file): 1753087 kB
Unevictable: 0 kB
Mlocked: 0 kB
SwapTotal: 2097148 kB
SwapFree: 2097148 kB
Dirty: 123 kB
Writeback: 0 kB
AnonPages: 580245 kB
Mapped: 234567 kB
Shmem: 123456 kB
KReclaimable: 87654 kB
Slab: 145678 kB
SReclaimable: 87654 kB
SUnreclaim: 58024 kB
KernelStack: 5678 kB
PageTables: 12345 kB
...

示例 7:性能调优场景

# ========== 场景 1:网络服务器 sk_buff 增长 ==========
# 表现:网卡丢包、网络延迟
# 检查:
$ sudo slabtop -o | grep -E "sk_buff"
OBJS ACTIVE USE OBJ SIZE SLABS OBJ/SLAB CACHE SIZE NAME
200000 180000 90% 0.25K 6250 32 200000K skbuff_head_cache
# 90% 使用率 = 接近上限,可能在网络高负载时丢包

# 解决:
# 1. 调整 netdev_max_backlog
$ sudo sysctl -w net.core.netdev_max_backlog=2000
# 2. 调整 socket 缓冲区
$ sudo sysctl -w net.core.rmem_max=12582912
$ sudo sysctl -w net.core.wmem_max=12582912

# ========== 场景 2:dentry 缓存不足 ==========
# 表现:磁盘 IO 高、stat() 慢
# 解决:调大 /proc/sys/vm/vfs_cache_pressure
$ cat /proc/sys/vm/vfs_cache_pressure
100
# 调小(保留更多 dentry)
$ sudo sysctl -w vm.vfs_cache_pressure=50

# ========== 场景 3:进程泄漏 task_struct ==========
# 表现:进程数持续增长
$ ps -e | wc -l
# 对应 slabtop 中 task_struct 增长
# 解决:定位并 kill 泄漏进程
$ ps aux –sort=-%mem | head -20
# 找出大内存进程

# ========== 场景 4:nf_conntrack 满 ==========
$ sudo slabtop -o | grep nf_conn
OBJS ACTIVE USE OBJ SIZE SLABS OBJ/SLAB CACHE SIZE NAME
262144 262144 100% 0.31K 8192 32 1048576K nf_conntrack
# 100% 使用 = 防火墙连接表已满,新连接被拒绝

# 解决:
$ sudo sysctl net.netfilter.nf_conntrack_max=524288
$ sudo sysctl net.netfilter.nf_conntrack_tcp_timeout_established=600
# 调大连接上限 + 缩短超时

示例 8:自动化分析与脚本

# ========== 1. slab 持续监控脚本 ==========
$ cat /opt/scripts/slab_watch.sh
#!/bin/bash
# 每 60 秒记录一次 slabtop 输出
LOG_DIR=/var/log/slab
mkdir -p $LOG_DIR

while true; do
TS=$(date +%F_%H%M%S)
slabtop -o > "$LOG_DIR/slab_$TS.txt"
# 清理 7 天前
find $LOG_DIR -name "slab_*.txt" -mtime +7 -delete
sleep 60
done

# ========== 2. 大 cache 告警 ==========
$ cat /opt/scripts/slab_alert.sh
#!/bin/bash
# 监控 cache > 1GB
THRESHOLD_KB=1048576 # 1GB

slabtop -o | tail -n +7 | awk -v thresh=$THRESHOLD_KB '
{
cache_kb = $7
gsub("K", "", cache_kb)
if (cache_kb > thresh) {
print "[ALERT] " $8 " cache 使用 " cache_kb "K 内存"
}
}'
| while read line; do
logger -p kern.warning "Slab: $line"
echo "$line"
# 可加钉钉/邮件通知
done

# ========== 3. 与其他监控集成 ==========
$ cat /opt/scripts/slab_to_prometheus.sh
#!/bin/bash
# 转换 slabtop 为 prometheus 文本格式
OUT=/var/lib/node_exporter/textfile/slab.prom
echo "# HELP slab_cache_bytes Total bytes used by kernel slab cache" > $OUT
echo "# TYPE slab_cache_bytes gauge" >> $OUT

slabtop -o | tail -n +7 | awk '
{
cache_kb = $7
gsub("K", "", cache_kb)
gsub("M", "000", cache_kb)
cache_bytes = cache_kb * 1024
name = $8
gsub("-", "_", name)
print "slab_cache_bytes{name=\\"" name "\\"} " cache_bytes
}'
>> $OUT

# prometheus node_exporter 采集
# 配合 grafana 画图


⚠️ 注意事项

1. 需要 root 权限 普通用户执行 slabtop 会显示受限数据,仅当 kernel.yama.ptrace_scope=0 且 /proc/slabinfo 全员可读。生产中必须 sudo。

2. /proc/slabinfo 内核选项 部分内核配置 CONFIG_SLAB 关闭时 /proc/slabinfo 不存在。 检查:

$ cat /proc/slabinfo 2>/dev/null | head
# 无输出 = 内核不导出

内核 < 2.6.32 或嵌入式系统可能没。

3. SLAB vs SLUB vs SLOB 输出差异

  • SLUB(现代默认):字段最全
  • SLAB(老内核):字段少
  • SLOB(嵌入式):几乎无数据 现代 Linux 都是 SLUB。

4. 高频率刷新影响 slabtop -d 1 每秒刷新,会持续读取 /proc/slabinfo。 大量 cache(几万)时,读取可能 10-50ms 延迟。 监控系统别用 < 5 秒间隔。

5. 排序字段大小写 slabtop -s a(活跃对象数)和 -s A(某些版本)含义不同。 用 –sort= 长格式更稳。

6. 名称中"-"的转义 很多 cache 名含 -(kmalloc-64、nf_conn)。 grep/awk 处理时用引号或转义。

7. 与 /proc/meminfo 的关系 slabtop 头部 “Used Memory” = /proc/meminfo 中 Slab 字段。 但只展示部分(不是全部 cache)。 完整数据看 /proc/slabinfo 原始文件。

8. 容器内的局限 Docker 默认 PID 命名空间隔离,容器内 slabtop 看到的是宿主机全局。 也可能因 cgroup 限制看到不同视图。

9. 数值单位 slabtop 默认千字节(K)。 OBJ SIZE 是单对象大小(带 K)。 实际 K = 1024 字节,不是 1000。

10. 优化建议 如果某个 cache 持续 100% 满且不能回收:

  • 检查驱动 bug(升级内核)
  • 调整 /proc/sys/vm/* 参数
  • 重启服务/系统(最后手段)
  • 启用 slab_nomerge(避免误合并)
  • 使用 BPF 工具做精细分析

  • 📝 总结

    slabtop 是"内核内存的 top"——专门看 slab 分配器。本节要点:

    • 核心定位:用户态内存用 top/ps,内核态内存用 slabtop
    • 关键字段:OBJS/ACTIVE/USE/OBJ SIZE/SLABS/CACHE SIZE/NAME
    • 诊断场景:
      • 内核内存增长 → 观察哪个 cache 在涨
      • dentry 增长 → 目录项泄漏/缓存压力
      • sk_buff 满 → 网络高负载
      • nf_conntrack 满 → 防火墙拒绝连接
    • 数据源:/proc/slabinfo(slabtop 是美化器)
    • 配合使用:
      • free(整体内存)
      • /proc/meminfo(slab 详细)
      • vmstat(slab 回收)
      • ps(用户态进程内存)

    最终建议:日常巡检 slabtop -s c -o 看最大 5 个 cache;内存告警 配合 /proc/meminfo 中 Slab 字段;深度诊断 用 perf / bpftool 抓具体内核对象;生产监控 导出 prometheus 指标。


    📚 相关命令

    命令用途
    slabtop 实时 slab 信息(本节)
    top / htop 用户态进程资源
    free 物理内存概览
    cat /proc/slabinfo slab 原始数据
    cat /proc/meminfo 详细内存信息
    vmstat 虚拟内存统计
    ps aux 进程详情
    pmap 进程内存映射
    sysctl 调整内核参数
    echo N > /proc/sys/vm/drop_caches 手动回收缓存
    perf 性能分析
    bpftool BPF 工具(高级)
    numastat NUMA 内存统计
    sysstat / sar -r 内存历史
    crash 内核转储分析(vmcore)
    赞(0)
    未经允许不得转载:网硕互联帮助中心 » Linux命令-slabtop(实时显示内核 slab 缓存信息)
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!