Linux内存异常:活跃进程使用的内存远远低于实际使用的内存

问题场景:

    今天早上收到报警,系统剩余内存低于15%;这台机器运行的服务为nginx,理论上占用的内存不会很多,于是进行排查;

    查看使用的内存:free -m

        image.png

    查看活跃进程使用的内存:ps aux --sort -rss | head

        image.png

    可以看到free -m使用的内存与前10个活跃进程使用的内存存在较在差距~

问题分析及解决:

    通过查阅资料,有可能是slab占用了内存;

    步骤一:安装atop工具,查看内存的具体使用情况

        yum install atop -y

        执行命令:atop

        image.png

        可以看到slab占用了2.6G的内存,确定了引用内存异常的原因是slab

    步骤二:查看slab占用内存的具体情况

        执行命令:cat /proc/meminfo | awk '{sum=$2/1024} {print $1 sum " MB"}' | grep claim

SReclaimable:3153.37 MB
SUnreclaim:25.0664 MB

        SReclaminable:表示可回收的slab占用的内存

        SUnreclaim:表示不可回收的slab占用的内存

        由此猜想,slab可回收的内存可以由系统进行自动回收或者手动回收

    步骤三:查看具体是什么占用了slab内存

        执行命令:slabtop

        image.png

        注:可以看到是dentry占用大部分的slab内存

        

        slab内存分类:

            pagecache

            dentries:目录项高速缓存

            inode


        slab是Linux操作系统的一种内存分配机制。其工作是针对一些经常分配并释放的对象,您可以看看哪些应用进程的slab占用的内存比较多,是否这些应用需要频繁的请求和释放内存,比如进行一些小文件的读写。如果都是应用的正常使用,可以考虑升级服务器内存,如果内存不足影响业务,需要临时释放一下slab占用的内存; 

        

        slab内存的释放策略:

            相关内核参数:vm.drop_caches

            参数值含义:

                0:不做任何处理,由系统自己管理

                1:清空pagecache

                2:清空dentries和inodes

                3:清空pagecache、dentries和inodes

    步骤四:手动回收slab中的可回收内存

        #将内存的数据同步到磁盘

        sync

        #清空slab中可回收的内存

        sudo sysctl -w vm.drop_caches=3  或者 echo 3 > /proc/sys/vm/drop_caches

        #内存回收后把内核参数改为原来的值

        sudo sysctl -w vm.drop_caches=0  或者 echo 0 > /proc/sys/vm/drop_caches

        注:以上修改的方式是临时生效

相关内核参数:

    vm.min_free_kbytes:保留给内核使用的;当到达min,系统会启动 kswapd 进行内存回收;此参数的默认值为67584; 

    

    可以通过此参数来的值让系统自动回收slab,但是此参数不宜设置过大;

    

    由此此参数引发的血案:

        生产中某台机器调高了此参数为1G,当系统free的内存小于1GB时,观察到kswapd进程开始工作(进程状态从Sleeping变为Running),同时dentry_cache开始被系统回收,直到系统free的内存介于low阈值和high阈值之间,停止回收。

        如果系统的free内存一直低于1G,则kswapd一直运行,造成系统持续较大压力!

    

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章