Linux cached內存占用過高處理


 

   之前更新一個服務,發現線程過大造成整個虛機卡死,后來增加線程池后,發現cached內存還是在持續增加,如下圖

 

 

 

 

考慮到該服務是多線程,且頻繁讀寫圖片,是否是資源未釋放,於是重啟服務,驗證緩存是否釋放,結果並未有所改變,如下圖:

 

 

 

再次排查,發現nohub.out文件大小與cached大小相近,於是刪除文件重啟服務,發現cached變小,問題解除,如下圖:

 

 

但是這里會並不能根本解決問題,幾天之后,日志還會變得很大,所以這里可以有2個方案處理

一、不產生nohub.out日志,命令如下:

   nohup java -jar /xxx/xxx/xxx.jar >/dev/null 2>&1 &

  >/dev/null 表示將標准輸出信息重定向到"黑洞";

  2>&1 表示將標准錯誤重定向到標准輸出(由於標准輸出已經定向到“黑洞”了,即:標准輸出此時也是"黑洞",再將標准錯誤輸出定向到標准輸出,

相當於錯誤輸出也被定向至“黑洞”)

 

二、將日志進行拆分

  

1、創建.sh文件,內容如下:

#!/bin/bash  

split -b 10m -d -a 4 ./nohup.out ./logs/nohup_log/nohup_$(date +\%Y\%m\%d)_

cat /dev/null > nohup.out

 

2、生成.sh文件存放在nohup.out同級目錄下,執行chmod +x spit_nohup.sh,進行賦權;

3、添加定時任務

   執行crontab -e,添加定時任務命令

 

 

 

 

---------------------分割線----------------下面是在排查過程中查到的一些基本資料------------------------------------------------------------------------------------------------

什么是buffer/cache?

buffer和cache是兩個在計算機技術中被用濫的名詞,放在不通語境下會有不同的意義。在Linux的內存管理中,這里的buffer指Linux內存的:Buffer cache。這里的cache指Linux內存中的:Page cache。翻譯成中文可以叫做緩沖區緩存和頁面緩存。在歷史上,它們一個(buffer)被用來當成對io設備寫的緩存,而另一個(cache)被用來當作對io設備的讀緩存,這里的io設備,主要指的是塊設備文件和文件系統上的普通文件。但是現在,它們的意義已經不一樣了。在當前的內核中,page cache顧名思義就是針對內存頁的緩存,說白了就是,如果有內存是以page進行分配管理的,都可以使用page cache作為其緩存來管理使用。當然,不是所有的內存都是以頁(page)進行管理的,也有很多是針對塊(block)進行管理的,這部分內存使用如果要用到cache功能,則都集中到buffer cache中來使用。(從這個角度出發,是不是buffer cache改名叫做block cache更好?)然而,也不是所有塊(block)都有固定長度,系統上塊的長度主要是根據所使用的塊設備決定的,而頁長度在X86上無論是32位還是64位都是4k。

明白了這兩套緩存系統的區別,就可以理解它們究竟都可以用來做什么了。

什么是page cache?

Page cache主要用來作為文件系統上的文件數據的緩存來用,尤其是針對當進程對文件有read/write操作的時候。如果你仔細想想的話,作為可以映射文件到內存的系統調用:mmap是不是很自然的也應該用到page cache?在當前的系統實現里,page cache也被作為其它文件類型的緩存設備來用,所以事實上page cache也負責了大部分的塊設備文件的緩存工作。

什么是buffer cache

Buffer cache則主要是設計用來在系統對塊設備進行讀寫的時候,對塊進行數據緩存的系統來使用。這意味着某些對塊的操作會使用buffer cache進行緩存,比如我們在格式化文件系統的時候。一般情況下兩個緩存系統是一起配合使用的,比如當我們對一個文件進行寫操作的時候,page cache的內容會被改變,而buffer cache則可以用來將page標記為不同的緩沖區,並記錄是哪一個緩沖區被修改了。這樣,內核在后續執行臟數據的回寫(writeback)時,就不用將整個page寫回,而只需要寫回修改的部分即可。

如何回收cache?

Linux內核會在內存將要耗盡的時候,觸發內存回收的工作,以便釋放出內存給急需內存的進程使用。一般情況下,這個操作中主要的內存釋放都來自於對buffer/cache的釋放。尤其是被使用更多的cache空間。既然它主要用來做緩存,只是在內存夠用的時候加快進程對文件的讀寫速度,那么在內存壓力較大的情況下,當然有必要清空釋放cache,作為free空間分給相關進程使用。所以一般情況下,我們認為buffer/cache空間可以被釋放,這個理解是正確的。

但是這種清緩存的工作也並不是沒有成本。理解cache是干什么的就可以明白清緩存必須保證cache中的數據跟對應文件中的數據一致,才能對cache進行釋放所以伴隨着cache清除的行為的,一般都是系統IO飆高。因為內核要對比cache中的數據和對應硬盤文件上的數據是否一致,如果不一致需要寫回,之后才能回收。

在系統中除了內存將被耗盡的時候可以清緩存以外,我們還可以使用下面這個文件來人工觸發緩存清除的操作:

[root@tencent64 ~]# cat /proc/sys/vm/drop_caches 
1

方法是:

echo 1 > /proc/sys/vm/drop_caches

當然,這個文件可以設置的值分別為1、2、3。它們所表示的含義為:

echo 1 > /proc/sys/vm/drop_caches:表示清除pagecache。
echo 2 > /proc/sys/vm/drop_caches:表示清除回收slab分配器中的對象(包括目錄項緩存和inode緩存)。slab分配器是內核中管理內存的一種機制,其中很多緩存數據實現都是用的pagecache。
echo 3 > /proc/sys/vm/drop_caches:表示清除pagecache和slab分配器中的緩存對象。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM