slab_unreclaimable内存为系统不可回收的内存,当其占用总内存的比例过高时,将会影响可用内存与系统性能。本文介绍如何排查Linux slab_unreclaimable内存占用高的原因。
问题现象
在Linux实例内运行cat /proc/meminfo | grep "SUnreclaim"命令查看SUnreclaim参数指标时,发现内存较大(例如SUnreclaim: 6069340 kB
),当该内存超过系统总内存大小的10%时,系统可能会存在slab内存泄漏。
可能原因
slab内存是内核组件(或驱动)通过调用kmalloc类接口向伙伴系统申请内存,然后内核组件(或驱动)没有正确释放内存所产生的。实例一旦出现slab内存泄漏,且无法通过kill
进程的方式回收内存,则只能通过重启实例解决。
slab内存泄漏会导致实例上运行的业务可用内存变少、内存碎片化,还会引起系统OOM Killer以及系统性能抖动。
解决方案
远程连接待排查问题的Linux实例。
具体操作,请参见连接方式概述。
运行以下命令,排查使用
objects
或内存较多,且内存不可回收的slab内存对应的名称。查看使用
objects
或内存最多的slab内存信息。slabtop -s -a
命令行返回结果中,您可以查看并记录
OBJ/SLAB
列数值较高的slab内存对应的名称(NAME
列)。确认slab内存是否为不可回收。
命令中的<slab NAME>变量需要手动修改为上一步中获取到的
OBJ/SLAB
列数值较高的slab内存对应的名称。cat /sys/kernel/slab/<slab NAME>/reclaim_account
例如,查看名称为
kmalloc-192
的slab内存是否为不可回收。cat /sys/kernel/slab/kmalloc-192/reclaim_account
查询结果为0时,表示slab内存不可回收;查询结果为1时,表示slab内存可回收。
排查slab_unreclaimable内存占用高的原因。
您可以使用crash工具进行静态分析,也可以使用perf工具进行动态分析,排查造成slab内存泄漏的原因。本文提供的示例场景中,实例对应的操作系统为Alibaba Cloud Linux 2操作系统,存在slab泄漏的内存名称为
kmalloc-192
。crash工具静态分析
运行以下命令,安装crash工具。
yum install crash -y
运行以下命令,安装内核调试工具kernel-debuginfo。
yum install kernel-debuginfo -y
运行以下命令,启动crash工具。
sudo crash
在crash工具内,运行以下命令,查看
kmalloc-192
内存统计信息。kmem -S kmalloc-192
内存统计信息较多时,您可以设置只显示最后几行(例如10行)信息。
kmem -S kmalloc-192 | tail -n 10
命令行的返回结果示例如下:
SLAB MEMORY NODE TOTAL ALLOCATED FREE ffffea004c94e780 ffff88132539e000 0 42 29 13 ffffea004cbef900 ffff88132fbe4000 0 42 40 2 ffffea000a0e6280 ffff88028398a000 0 42 40 2 ffffea004bfa8000 ffff8812fea00000 0 42 41 1 ffffea006842b380 ffff881a10ace000 0 42 41 1 ffffea0009e7dc80 ffff880279f72000 0 42 34 8 ffffea004e67ae80 ffff881399eba000 0 42 40 2 ffffea00b18d6f80 ffff882c635be000 0 42 42 0
以
ffff88028398a000
统计信息为例,空闲内存较少(FREE
列),已分配的内存较多(ALLOCATED
列)。在crash工具内,运行以下命令,查看
ffff88028398a000
内存信息。rd ffff88028398a000 512 -S
命令行的返回信息较长,您可以根据命令行提示打印多个页面数据进行分析。例如:
返回信息中多次出现
put_cred_rcu
函数时,您可以自行查看Linux内核源码,搜索put_cred_rcu
函数。void __put_cred(struct cred *cred) { call_rcu(&cred->rcu, put_cred_rcu); }
查看到
put_cred_rcu
函数用于异步释放cred,且put_cred_rcu
出现在cred的末尾,表示是内核中cred结构体出现了slab内存泄漏。
perf工具动态分析
运行以下命令,安装perf工具。
yum install perf -y
运行以下命令,使用perf工具动态获取
kmalloc-192
中没有释放的内存,动态获取数据的时间间隔为200秒。perf record -a -e kmem:kmalloc --filter 'bytes_alloc == 192' -e kmem:kfree --filter ' ptr != 0' sleep 200
在当前目录下,将动态获取的数据打印至临时文件中。
本示例中,临时文件名称为testperf.txt。
perf script > testperf.txt
运行以下命令,查看testperf.txt文件内容。
cat testperf.txt
您需要手动排查没有空闲内存(
free
)的内存信息,然后在Linux内核源代码中手动查询产生slab内存泄漏的函数。说明动态获取的信息较多,建议您在专业运维人员的指导下完成问题排查。