分析Linux的Slab内存使用
分析Linux的Slab内存使用
Linux系统内存管理中,Slab是内核用于高效分配小块内存的重要机制。通过分析Slab内存使用情况,可以有效发现内核内存泄漏、缓存过度占用等问题。
常见Slab内存问题排查
内核缓存异常增长,系统内存不足
具体的现象可能如下:
# free -h 显示可用内存很少
total used free shared buff/cache available
Mem: 15Gi 2.1Gi 256Mi 128Mi 13Gi 12Gi
# 但是drop cache后内存回收有限
echo 3 > /proc/sys/vm/drop_caches
为什么 free会显示可用内存很少,却drop不掉呢???? 因为used内存里是计算了Slab内存的,如果Slab占用过大,就会表现为free可用值很少!!
使用工具来定位
通过 /proc/slabinfo
查看内核缓存统计:
# slabinfo - version: 2.1
# name <active_objs> <num_objs> <objsize> <objperslab> <pagesperslab> : tunables <limit> <batchcount> <sharedfactor> : slabdata <active_slabs> <num_slabs> <sharedavail>
dentry 350000 351000 192 42 2 : tunables 0 0 0 : slabdata 8357 8357 0
inode_cache 180000 180900 608 13 2 : tunables 0 0 0 : slabdata 13915 13915 0
kmalloc-1024 45000 45000 1024 16 4 : tunables 0 0 0 : slabdata 2812 2812 0
可以看到,某些缓存项异常增长:
- dentry缓存:35万个对象,占用约67MB
- inode_cache:18万个对象,占用约109MB
- kmalloc-1024:4.5万个对象,占用约45MB
这些缓存无法通过 drop_caches
释放,说明存在内核对象泄漏。
但是有个麻烦的地方:
- /proc/slabinfo 输出的内容很多,而且不容易查看!!
- /proc/slabinfo 中一般出现问题时,是缓慢的数据变化,比如:缓慢的增长,人肉眼比较难以察觉!
所以,Ctbots.com 先做了一版本简易功能,来解决这个问题。
https://ctbots.com/zh/linux/performance/slabinfo.html
工具使用起来非常简单,主要分为三步:
按照指示,生成shell指令去执行,会记录log信息。
下载指定的输出log文件夹的内容到本地。
上传log文件夹的内容到 Ctbots.com 分析,直接可以查看在线表格,对比搜索差异。
直接使用 分析功能,简单地分析是否存在泄漏。
Slab内存问题分析
为什么会出现这种情况?
- 应用程序频繁创建文件但未正确关闭,导致dentry/inode缓存积累
- 内核模块存在内存泄漏,持续分配kmalloc对象不释放
- 文件系统异常,无法正常回收缓存对象
内核Slab内存管理包含多个缓存池:
- dentry缓存:目录项缓存,用于加速文件路径解析
- inode缓存:索引节点缓存,存储文件系统元数据
- kmalloc缓存:通用内存分配器,按大小分类
- 专用缓存:如skbuff_head_cache网络缓存等
发现Slab问题了,怎么办?
根据ctbots工具的分析建议:
dentry/inode缓存过多
# 检查打开文件数量
lsof | wc -l
# 查看进程文件句柄使用
lsof -p <pid> | wc -l
# 调整内核参数限制缓存大小
echo 100000 > /proc/sys/fs/dentry-state
kmalloc泄漏排查
# 检查内核模块内存使用
cat /proc/modules | grep -v '0$'
# 查看内核内存分配统计
cat /proc/meminfo | grep -i slab
# 使用kmemleak检测内核内存泄漏(需要内核支持)
echo scan > /sys/kernel/debug/kmemleak
cat /sys/kernel/debug/kmemleak
网络缓存异常
# 检查网络连接状态
ss -tuln | wc -l
# 查看网络缓存统计
cat /proc/net/sockstat
如果怀疑网络连接存在泄漏,可以Ctbots.com 发现Tcp 或者 Udp的连接泄漏。
https://ctbots.com/zh/linux/findBug/performanceIndex.html
在菜单中可以看到Tcp和Udp的连接泄漏排查工具。