先看现象。八 G 内存的 CentOS 7.9 上 free 显示可用只剩几百 M,缓存和缓冲区占掉大半,/proc/meminfo 里 Slab 有六 G,SReclaimable 占了绝大头。

真正麻烦的地方在于,几个原因的现象几乎一样。目录被遍历了几百万次,dentry 和 inode 缓存不断累积。另一种情况是每分钟的全盘 find 把每个文件都塞进了 dcache。

还有一种情况,文件系统挂载之后没有回收,缓存只能靠内存压力被动释放。

另外,监控脚本 stat 了大量小文件,缓存长期不降温。

先确认 Slab 里主要是哪一类

slabtop -o | head -10

接着看 dentry 和 inode 的数量

grep -E 'dentry|inodes_cache' /proc/slabinfo | head

手工回收可回收的 Slab

sync && echo 2 > /proc/sys/vm/drop_caches

剩下的就是找出谁在反复扫盘

cat /proc/loadavg && ps -eo pid,cmd --sort=-%cpu | head

排查用的命令都是临时敲的,没有写成脚本,事后才整理。

怎么算真的好了,看的是同一批现象。Slab 占用从六 G 降到一 G 以内,SReclaimable 同步下降,free 的可用内存回到三 G 以上。

补一句。Slab 里的可回收部分是缓存,不一定是泄漏;真正要做的是把全盘 find 换成带时间戳的增量扫描,否则清完很快又涨回来。这类问题最好一次改到位,反复小改反而容易把原因搅混。

作者 9823189