商城首页欢迎来到中国正版软件门户

您的位置: 首页 > 文章列表 > 系统应用 > Linux怎么查看空间未释放导致的异常占

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

  发布于2026-08-17 阅读(0)

扫一扫,手机访问

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

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

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

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

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

  • MemA vailable 持续掉,Slab 持续涨 → 内核态泄漏嫌疑极大
  • Slab 高但 SReclaimable 占比超 80% → 大概率是可回收缓存(如 dentry、inode),不是泄漏
  • KernelStack 突增或波动剧烈 → 可能是内核栈溢出或递归过深,不是 slab 泄漏

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

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

重点关注:

  • kmalloc-* 系列(如 kmalloc-2048)→ 通用内存池,驱动或模块分配后忘 free 的高发区
  • nf_conntrack_* → 连接跟踪表泄漏,常见于高并发短连接场景
  • dentry / inode_cache → 如果 SReclaimable 同步高,先别急着判泄漏,可能是目录遍历或 unlinked 文件残留

注意:单次输出意义不大,必须间隔 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,但重启模块后它还在涨。这时候要检查三点:

  • 该缓存是否被多个模块共用?比如网卡驱动和 iptables 模块都调 kmem_cache_alloc,得结合 slabinfoname 列和模块加载顺序交叉验证
  • slabinfo 第 4 列(objsize)是否和你怀疑的结构体大小吻合?比如你查 struct sk_buff,它的典型大小是 224 字节,对应缓存名往往是 skbuff_head_cache,不是 kmalloc-256
  • 有没有用户态程序通过 ioctlsysfs 接口反复触发内核分配?比如某些监控 agent 会高频读取 /sys/class/net/*/statistics,间接导致 ethtool 相关缓存膨胀
本文转载于:https://www.php.cn/faq/2994520.html 如有侵犯,请联系zhengruancom@outlook.com删除。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。

热门关注