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% 满且不能回收:
📝 总结
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) |
网硕互联帮助中心




评论前必须登录!
注册