inux系统内存消失与slab使用之谜
上周发现我们的一台应用服务器上面的内存莫名其妙被吃光,查看所有进程所使用的内存实际只占用了14G左右
[root@app]# ps aux|awk '{sum+=$6} END {print sum/1024}' 14457.2
按照系统的内存32G来算,应该还有17G左右可用,但是查看可用内存却只有2487M
[root@app]# free -m total used free shared buffers cached Mem: 32177 32084 93 0 1612 782 -/+ buffers/cache: 29690 2487 Swap: 0 0 0
那么还有15G左右的内存去哪了呢?
进一步查看meminfo
[root@app]# cat /proc/meminfo MemTotal: 32949824 kB MemFree: 99736 kB Buffers: 1423264 kB Cached: 1419108 kB SwapCached: 0 kB Active: 15054636 kB Inactive: 1275644 kB HighTotal: 0 kB HighFree: 0 kB LowTotal: 32949824 kB LowFree: 99736 kB SwapTotal: 0 kB SwapFree: 0 kB Dirty: 131728 kB Writeback: 0 kB AnonPages: 13487512 kB Mapped: 18640 kB Slab: 16370936 kB PageTables: 93860 kB NFS_Unstable: 0 kB Bounce: 0 kB CommitLimit: 16474912 kB Committed_AS: 16199820 kB VmallocTotal: 34359738367 kB VmallocUsed: 264192 kB VmallocChunk: 34359473391 kB HugePages_Total: 0 HugePages_Free: 0 HugePages_Rsvd: 0 Hugepagesize: 2048 kB
其中的slab,查看相关资料:
通常的说法是:内核数据结构缓存的大小,可以减少申请和释放内存带来的消耗
这里的说法太笼统了
详细的说法如下:
在linux内核中会有许多小对象,这些对象构造销毁十分频繁,比如i-node,dentry。这么这些对象如果每次构建的时候就向内存要一个页,而其实际大小可能只有几个字节,这样就非常浪费,为了解决这个问题就引入了一种新的机制来处理在同一页框中如何分配小存储器区,这个机制可以减少申请和释放内存带来的消耗,这些小存储器区的内存称为Slab
在suse和ubuntu中查看meminfo会发现他们将slab分的很清楚,包括SReclaimable和SUnreclaim
其中SReclaimable指可收回Slab的大小,SUnreclaim不可回收的slab大小,但是在redhat之中没有进行区分
通过查看服务器上面的inode(使用df -i),发现已经占用了40%,与同事沟通时发现report_data/generate 目录下很多小文件,造成了大量占用inode,删除掉部分之后,目前inode还占用了16%
[root@app]# df -i /dev/mapper/kw-DATA 53248000 8106118 45141882 16% /mnt/DATA
这时候可用内存达到了差不多10G左右,meminfo中的slab占用在4G左右了。