判断内核态泄漏,关键不是盯住单一指标,而是看几个信号有没有一起出现:Slab 和 SUnreclaim 是否同步且持续走高,同时 MemA vailable 是否在往下掉;如果 SReclaimable 的占比已经超过 80%,那通常说明更多是可回收缓存堆积,并不属于泄漏;另外,若 KernelStack 突然明显上升,往往指向的是栈溢出问题,而不是 slab 泄漏。

Linux怎么查看空间未释放导致的异常占

直接看 /proc/meminfo 里的 SlabSUnreclaim,如果这两项持续上涨而 MemA vailable 同步下降,基本就是内核空间没释放导致的异常占用。

怎么区分是缓存还是真泄漏

Linux 的“高内存占用”不等于“泄漏”。关键看三组数字是否同步变化:

执行一次快照对比最直观:

watch -n 5 "grep -E 'MemA vailable|Slab|SReclaimable|SUnreclaim|KernelStack' /proc/meminfo"

盯住 SUnreclaim:它代表 slab 中**不可回收**的部分,只要它每分钟稳定增长几十 KB 以上,就该拉响警报。

定位具体哪个 slab 缓存在吃内存

/proc/slabinfo 是唯一可信来源,但原始输出太乱。用这个命令按“未释放对象数”排序:

awk '$2 > $3 {print $1, $2-$3, int($2/$3*100)/100}' /proc/slabinfo | sort -k2 -nr | head -10

重点关注:

注意:单次输出意义不大,必须间隔 5–15 分钟采两次,算差值。比如 kmalloc-4096 从 12000 → 12800,说明 10 分钟新增了 800 个未释放对象。

确认是不是 kmemleak 能抓到的泄漏

如果内核编译时启用了 CONFIG_DEBUG_KMEMLEAK(多数云厂商定制内核已开),可以直接用 kmemleak 扫描:

先确保 debugfs 已挂载:

mount -t debugfs nodev /sys/kernel/debug/

触发一次扫描并查看结果:

echo scan > /sys/kernel/debug/kmemleak
cat /sys/kernel/debug/kmemleak | head -20

如果看到类似这样的输出:

unreferenced object 0xffff888123456000 (size 256):
comm "ksoftirqd/0", pid 9, jiffies 4321098765
backtrace:
[] kmemleak_alloc+0x4c/0xb0
[] kmem_cache_alloc+0x1fe/0x2f0
[] my_driver_rx_handler+0x8a/0x120

这基本意味着,泄漏点已经可以收敛到具体模块和函数层面了,比如 my_driver_rx_handler。不过有个细节很容易被忽略:kmemleak 默认是每 10 分钟才自动扫描一次,而且更早发生的分配未必能顺利进入日志。所以一旦发现异常,最好立刻手动执行 echo scan,别拖。

容易被忽略的硬伤

很多排查卡在最后一步:你以为锁定了 kmalloc-1024,但重启模块后它还在涨。这时候要检查三点:

本文转载于:https://www.php.cn/faq/2994520.html 如有侵犯,请联系zhengruancom@outlook.com删除。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。