linux内存占用问题调查——slab

1、问题描述:

最近在维护一台CentOS服务器的时候,发现内存无端"损失"了许多,free和ps统计的结果相差十几个G,登上去发现:

$ free -g
             total       used       free     shared    buffers     cached
Mem:            15         15          0          0          2          0
-/+ buffers/cache:         12          2
Swap:           17          0         17

这台服务器有16G内存,但是结果显示除了2G左右的文件Buffer缓存外,其余十几G都被确确实实的用光了。

free命令各个列含义:

/ total used free shared buffers cached
Mem总物理内存当前使用的内存(包括slab+buffers+cached)完全没有使用的内存进程间共享的内存缓存文件的元数据[1]缓存文件的具体内容[1]
-/+ buffers/cache 当前使用的内存(不包括buffers+cached,但包括slab)未使用和缓存的内存(free+buffers+cached)   
Swap总的交换空间已使用的交换空间未使用的交换空间
然后top看了下,没有特别吃内存的程序。用ps大概统计下所有程序占用的总内存:

$ ps aux | awk '{mem += $6} END {print mem/1024/1024}'
0.595089

结果显示所有进程占用的内存还不到1G,实际上,因为free, ps的统计方式的差别和Copy-on-write(http://wiki.osdev.org/Paging)和Shared libraries等内存优化机制的存在,这两者的统计结果通常是不一样的。但是一般情况下绝对不会相差十几个G,肯定是有什么隐藏的问题,Google了许久后发现,free没有专门统计另一项缓存: Slab。


2、Slab简介和进一步调查

Slab Allocation是Linux 2.2之后引入的一个内存管理机制,专门用于缓存内核的数据对象,可以理解为一个内核专用的对象池,可以提高系统性能并减少内存碎片。(Linux 2.6.23之后,SLUB成为了默认的allocator。)

1)查看Slab缓存

$ cat /proc/meminfo

其中,Slab相关的数据为

Slab:             154212 kB
SReclaimable:      87980 kB
SUnreclaim:        66232 kB

SReclaimable(Linux 2.6.19+)都是clean的缓存,随时可以释放。回到之前的内存问题,我查了下那台服务器上Slab占用的内存:

$ cat /proc/meminfo | grep Slab
Slab:         12777668 kB

12G的Slab缓存,有意思的是free把Slab缓存统计到了used memory中,这就是之前那个问题的症结所在了。


2)另外,还可以查看/proc/slabinfo(或使用slabtop命令)来查看Slab缓存的具体使用情况。结果发现,ext3_inode_cache和dentry_cache占用了绝大部分内存。考虑到这台服务器会频繁地用rsync同步大量的文件,这个结果也并不意外。


3、解决问题:

先说明一下,如果问题仅仅是Slab占用了太多的内存(SReclaimable),那么通常不需要太操心,因为这根本不是个问题(如果是SUnreclaim太多且不断增长,那么很有可能是内核有bug)。但是,如果是因为Slab占用内存太多而引起了其他的问题,建议继续阅读。

1)手工清除Slab可回收缓存:

echo 2 > /proc/sys/vm/drop_caches

上面的命令会主动释放Slab中clean的缓存(包括inode和dentry的缓存),然后再free -g一下,未使用的内存陡增了十几个G。。。

注:手动清除缓存可能会在一段时间内降低系统性能。原则上不推荐这么做,因为如果有需要,系统会自动释放出内存供其他程序使用。

另外,手动清除Slab缓存是一个治标不治本的办法。因为问题不在Slab,而在于我们那个会引起Slab缓存飙涨的进程(我这里应该是rsync)。实际操作的时候发现,清除缓存一段时间后,Slab缓存很快又会“反弹”回去。如果需要治本,要么搞定问题进程,要么修改系统配置。


2)调整系统vm配置

vm.vfs_cache_pressure
系统在进行内存回收时,会先回收page cache, inode cache, dentry cache和swap cache。vfs_cache_pressure越大,每次回收时,inode cache和dentry cache所占比例越大。vfs_cache_pressure默认是100,值越大inode cache和dentry cache的回收速度会越快,越小则回收越慢,为0的时候完全不回收(OOM!)。


vm.min_free_kbytes
系统的"保留内存"的大小,"保留内存"用于低内存状态下的"atomic memory allocation requests"(eg. kmalloc + GFP_ATOMIC),该参数也被用于计算开始内存回收的阀值,默认在开机的时候根据当前的内存计算所得,越大则表示系统会越早开始内存回收。
注:min_free_kbytes过大可能会导致OOM,太小可能会导致系统出现死锁等问题。


vm.swappiness
该配置用于控制系统将内存swap out到交换空间的积极性,取值范围是[0, 100]。swappiness越大,系统的交换积极性越高,默认是60,如果为0则不会进行交换。



参考:https://www.mawenbao.com/research/linux-ate-my-memory.html

  • 1
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
当我们说“slab占用过高”时,通常指的是在Linux系统中,slab内存缓存的使用量超出了正常范围。对于这个问题,我们可以采取以下步骤进行排查和解决: 1. 确认问题:通过查看系统的内存使用情况,特别是slab缓存的使用量,可以使用命令“free -m”或“top”来查看。如果slab缓存占用内存比较大,可能存在问题。 2. 检查slab缓存类型:使用命令“slabtop”可以查看slab缓存的类型及其占用内存大小。特别是注意查看占用内存最大的缓存类型。 3. 检查进程和应用程序:有些进程或应用程序可能会频繁创建和释放内存对象,导致slab缓存过度膨胀。通过使用工具如“top”或“ps aux”命令,找出占用内存较多的进程或应用程序,并分析它们的内存使用模式。 4. 检查内核模块和驱动程序:一些内核模块或驱动程序可能会导致slab缓存异常增长。可以通过查看“lsmod”命令列出的加载的内核模块,或使用“lsof”命令查看打开的文件和网络连接来进行排查。 5. 限制slab缓存的大小:在某些情况下,可以通过修改内核参数来限制slab缓存的大小。具体的参数设置可以参考相关的文档或咨询Linux系统管理员。 6. 更新或回滚内核版本:有时,slab缓存问题可能是由于特定内核版本的bug所致。如果发现问题出现在特定的内核版本上,可以尝试升级或回滚到另一个内核版本来解决问题。 通过以上步骤,并结合具体的使用情况和系统配置,我们应该能够找出并解决“slab占用过高”的问题。如果问题仍然存在,建议进一步咨询Linux系统专家或相关技术支持。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

赶路人儿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值