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一直運行,造成系統持續較大壓力!

    

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