1. 程式人生 > >Cache佔用過多記憶體導致Linux系統記憶體不足問題排查

Cache佔用過多記憶體導致Linux系統記憶體不足問題排查

問題描述

Linux伺服器記憶體使用量超過閾值,觸發報警。

問題排查

首先,通過free命令觀察系統的記憶體使用情況,顯示如下:

  1. total       used       free     shared    buffers     cached 
  2. Mem:      24675796   24587144      88652          0     357012    1612488 
  3. -/+ buffers/cache:   22617644    2058152 
  4. Swap:      2096472     108224    1988248 

其中,可以看出記憶體總量為24675796KB,已使用22617644KB,只剩餘2058152KB。

然後,接著通過top命令,shift + M按記憶體排序後,觀察系統中使用記憶體最大的程序情況,發現只佔用了18GB記憶體,其他程序均很小,可忽略。

因此,還有將近4GB記憶體(22617644KB-18GB,約4GB)用到什麼地方了呢?

進一步,通過cat /proc/meminfo發現,其中有將近4GB(3688732 KB)的Slab記憶體:

  1. ...... 
  2. Mapped:          25212 kB 
  3. Slab:          3688732 kB 
  4. PageTables:      43524 kB 
  5. ...... 

Slab是用於存放核心資料結構快取,再通過slabtop命令檢視這部分記憶體的使用情況:

  1. OBJS ACTIVE  USE OBJ SIZE  SLABS OBJ/SLAB CACHE SIZE NAME 
  2. 13926348 13926348 100%    0.21K 773686       18   3494744K dentry_cache 
  3. 334040 262056  78%    0.09K   8351       40     33404K buffer_head 
  4. 151040 150537  99%    0.74K  30208        5    120832K ext3_inode_cache 

發現其中大部分(大約3.5GB)都是用於了dentry_cache。

問題解決

1. 修改/proc/sys/vm/drop_caches,釋放Slab佔用的cache記憶體空間(參考drop_caches的官方文件):

  1. Writing to this will cause the kernel to drop clean caches, dentries and inodes from memory, causing that memory to become free. 
  2. To free pagecache: 
  3. * echo 1 > /proc/sys/vm/drop_caches 
  4. To free dentries and inodes: 
  5. * echo 2 > /proc/sys/vm/drop_caches 
  6. To free pagecache, dentries and inodes: 
  7. * echo 3 > /proc/sys/vm/drop_caches 
  8. As this is a non-destructive operation, and dirty objects are notfreeable, the user should run "sync" first in order to make sure allcached objects are freed. 
  9. This tunable was added in 2.6.16. 

2. 方法1需要使用者具有root許可權,如果不是root,但有sudo許可權,可以通過sysctl命令進行設定:

  1. $sync 
  2. $sudo sysctl -w vm.drop_caches=3
  3. $sudo sysctl -w vm.drop_caches=0 #recovery drop_caches 

操作後可以通過sudo sysctl -a | grep drop_caches檢視是否生效。

3. 修改/proc/sys/vm/vfs_cache_pressure,調整清理inode/dentry caches的優先順序(預設為100),LinuxInsight中有相關的解釋:

  1. At the default value of vfs_cache_pressure = 100 the kernel will attempt to reclaim dentries and inodes at a “fair” rate with respect to pagecache and swapcache reclaim. Decreasing vfs_cache_pressure causes the kernel to prefer to retain dentry and inode caches. Increasing vfs_cache_pressure beyond 100 causes the kernel to prefer to reclaim dentries and inodes.  

具體的設定方法,可以參考方法1或者方法2均可。

參考資料

  • https://www.kernel.org/doc/Documentation/sysctl/vm.txt
  • http://major.io/2008/12/03/reducing-inode-and-dentry-caches-to-keep-oom-killer-at-bay/
  • http://linux-mm.org/Drop_Caches

以下記錄的是進一步排查的進展情況。

更深層次的原因

上文排查到Linux系統中有大量的dentry_cache佔用記憶體,為什麼會有如此多的dentry_cache呢?

1. 首先,弄清楚dentry_cache的概念及作用:目錄項快取記憶體,是Linux為了提高目錄項物件的處理效率而設計的;它記錄了目錄項到inode的對映關係。因此,當應用程式發起stat系統呼叫時,就會建立對應的dentry_cache項(更進一步,如果每次stat的檔案都是不存在的檔案,那麼總是會有大量新的dentry_cache項被建立)。

2. 當前伺服器是storm叢集的節點,首先想到了storm相關的工作程序,strace一下storm的worker程序發現其中有非常頻繁的stat系統呼叫發生,而且stat的檔案總是新的檔名:

sudo strace -fp <pid> -e trace=stat

3. 進一步觀察到storm的worker程序會在本地目錄下頻繁的建立、開啟、關閉、刪除心跳檔案,每秒鐘一個新的檔名:

sudo strace -fp <pid> -e trace=open,stat,close,unlink

以上就是系統中為何有如此多的dentry_cache的原因所在。

一個奇怪的現象

通過觀察/proc/meminfo發現,slab記憶體分為兩部分:

SReclaimable // 可回收的slab
SUnreclaim // 不可回收的slab

當時伺服器的現狀是:slab部分佔用的記憶體,大部分顯示的都是SReclaimable,也就是說可以被回收的。

但是通過slabtop觀察到slab記憶體中最主要的部分(dentry_cache)的OBJS幾乎都是ACTIVE的,顯示100%處於被使用狀態。

OBJS ACTIVE  USE OBJ SIZE  SLABS OBJ/SLAB CACHE SIZE NAME                   
13926348 13926348 100%    0.21K 773686       18   3494744K dentry_cache
334040 262056  78%    0.09K   8351       40     33404K buffer_head
151040 150537  99%    0.74K  30208        5    120832K ext3_inode_cache

為什麼顯示可回收的,但是又處於ACTIVE狀態呢?求Linux核心達人看到後熱心解釋下:(

會不會由於是ACTIVE狀態,導致dcache沒有被自動回收釋放掉呢?

讓系統自動回收dcache

上一小節,我們已經提到,伺服器上大部分的slab記憶體是SReclaimable可回收狀態的,那麼,我們能不能交給作業系統讓他在某個時機自動觸發回收操作呢?答案是肯定的。

查了一些關於Linux dcache的相關資料,發現作業系統會在到了記憶體臨界閾值後,觸發kswapd核心程序工作才進行釋放,這個閾值的計算方法如下:

1. 首先,grep low /proc/zoneinfo,得到如下結果:

        low      1
        low      380
        low      12067

2. 將以上3列加起來,乘以4KB,就是這個閾值,通過這個方法計算後發現當前伺服器的回收閾值只有48MB,因此很難看到這一現象,實際中可能等不到回收,作業系統就會hang住沒響應了。

3. 可以通過以下方法調大這個閾值:將vm.extra_free_kbytes設定為vm.min_free_kbytes和一樣大,則/proc/zoneinfo中對應的low閾值就會增大一倍,同時high閾值也會隨之增長,以此類推。

$ sudo sysctl -a | grep free_kbytes       
vm.min_free_kbytes = 39847
vm.extra_free_kbytes = 0
$ sudo sysctl -w vm.extra_free_kbytes=836787  ######1GB

4. 舉個例子,當low閾值被設定為1GB的時候,當系統free的記憶體小於1GB時,觀察到kswapd程序開始工作(程序狀態從Sleeping變為Running),同時dcache開始被系統回收,直到系統free的記憶體介於low閾值和high閾值之間,停止回收。

相關推薦

Cache佔用過多記憶體導致Linux系統記憶體不足問題排查

問題描述 Linux伺服器記憶體使用量超過閾值,觸發報警。 問題排查 首先,通過free命令觀察系統的記憶體使用情況,顯示如下: total       used       free     shared    buffers     cached Mem:   

Linux記憶體buff/cache佔用過多問題解決

在Linux下經常會遇到buff/cache記憶體佔用過多問題,尤其是使用雲主機的時候最嚴重,由於很多是虛擬記憶體,因此如果buff/cache佔用過大的,free空閒記憶體就很少,影響使用;通常記憶體

檢視Linux系統記憶體的真實佔用

Linux啟動新的程序的時候會優先使用實體記憶體,當實體記憶體還有空閒時,linux是不會釋放記憶體的(只要還有空間,那麼程序就在可用空間中啟動,而不是先清理一下記憶體然後再啟動新的程序),即使佔用記憶體的程式已經被關閉了(這部分記憶體就用來做快取了)。也就是說

Linux系統記憶體佔用90%以上——解決方法

最近遇到一個疑問,不管是top,還是cat /proc/meminfo,  發現free記憶體基本快沒了,難道我們的程式出問題了?排查半天沒有事, 後來百度到相關帖子,記錄一下,這是Linux核心機制, Linux與Windows不同,會存在快取記憶體,通常叫做Cac

Linux系統記憶體管理之夥伴系統分析

 1.夥伴系統概念   夥伴系統是一種經典的記憶體管理方法。Linux夥伴系統的引入為核心提供了一種用於分配一組連續的頁而建立的一種高效的分配策略,並有效的解決了外碎片問題。  2.夥伴系統的組織結構 Linux中的記憶體管理的“頁”大小為4KB。把所有的空閒頁分組

Linux系統記憶體磁碟初始化技術詳細解析

轉http://unix-cd.com/unixcd12/article_6520.html initrd掛載優先順序高於真實根檔案系統,它被邦定在核心上,做為核心啟動過程的一部分被載入(load)。然後,做為兩階段引導過程的第一部分,核心掛載(mount)initrd,用

Nginx配置及linux系統記憶體高併發多方面優化

基於網上的技術文章思路,自己加以整理,有常用的和不常用的策略,供參考。 nginx的優化 1. gzip壓縮優化 2. expires快取有還 3. 網路IO事件模型優化 4. 隱藏軟體名稱和版本號 5. 防盜鏈優化 6. 禁止惡

正確計算linux系統記憶體使用率

圖中的例子很典型,就是:多數的linux系統在free命令後會發現free(剩餘)的記憶體很少,而自己又沒有開過多的程式或服務。對於上述的情況,正確的解釋是:linux的記憶體管理機制與windows的有所不同。具體的機制我們無需知道,我們需要知道的是,linux的記憶體管理機制的思想包括(不

系統技術非業餘研究 » Linux系統記憶體相關資訊獲取

大型的伺服器,特別是資料庫伺服器的主要瓶頸主要在記憶體,CPU,以及IO上。CPU是可再生資源,不夠用等等就有了;記憶體和土地一樣是不可再生資源,被佔用了,後續的使用必須等到該資源釋放.而IO也非常依賴於記憶體的使用情況,故記憶體的倒騰效率會大大影響伺服器的效率,那麼瞭解伺服器記憶體的使用情況就非

Linux系統記憶體監控全面講解之free命令

   [[email protected] tmp]# free total used free shared buffers cached Mem: 3266180 3250004 16176 0 110652 2668236 -/+ buffers/cache: 471116 2795

Linux系統記憶體消失與slab使用之謎

上週發現我們的一臺應用伺服器上面的記憶體莫名其妙被吃光,檢視所有程序所使用的記憶體實際只佔用了14G左右 [root@app]# ps aux|awk '{sum+=$6} END {print sum/1024}' 14457.2 按照系統的記憶體32G來算,應該還有17G左右可用,但是檢視可用記

幫助你檢查Linux系統記憶體及其使用情況的命令

浪費了“黃金五年”的Java程式設計師,還有救嗎? >>>   

Cgroup限制CPU、IO、記憶體以及linux系統中的排程策略

一、CPU 1、0核利用 思路: 0核是必須要保護的,否則各種系統命令、喂狗都可能出問題;    &

【檢視記憶體Linux檢視記憶體使用情況(一)

用 'top -i' 看看有多少程序處於 Running 狀態,可能系統存在記憶體或 I/O 瓶頸,用 free 看看系統記憶體使用情況,swap 是否被佔用很多,用 iostat 看看 I/O 負載情況... 還有一種辦法是 ps -ef | sort -k7 ,將程序按執行時間排序,看哪個程序消耗的cp

誤刪除glic導致linux系統崩潰的處理辦法

示例環境 此文件的執行環境為: centos 6.5系統 vmware6.0虛擬機器 誤操作場景 導致伺服器出問題是在將glibc的版本由2.14降至2.12的過程中,修改glibc.so.6檔案軟連線的時候誤操作,將glibc.so.6重新命名錯誤

Linux伺服器java程序佔用系統記憶體

使用top命令檢視系統資源的使用情況,命令:top 如圖可以看到java的程序記憶體使用率較高,java程序的記憶體使用率達到了70%+ 2.定位執行緒問題(通過命令檢視9718程序的執行緒情況),命令:ps p 9718 -L -o pcpu,pmem,pid,tid,time

轉載-linux下釋放被cache佔用的實體記憶體

當你在Linux下頻繁存取檔案後,實體記憶體會很快被用光,當程式結束後,記憶體不會被正常釋放,而是一直作為caching.這個問題,貌似有不少人在問,不過都沒有看到有什麼很好解決的辦法.那麼我來談談這個問題. 先來說說free命令 [[email

Linux系統used記憶體佔用很大,而實際系統中個程序並沒有佔用這麼多記憶體

問題 新裝伺服器,used記憶體佔用很大,而實際系統中個程序並沒有佔用這麼多記憶體 現象 top檢視下,used很大,如果有其他外部程式向監控伺服器的記憶體,used實際是個比較關鍵的指標,而該指標卻並沒有反應出伺服器實際佔用情況: 原因 實

如何釋放linux cache佔用記憶體

[[email protected] ~]# free -m              total       used       free     shared    buffers     cached Mem:          3792       3663        128    

Java程式在linux系統下執行,為什麼會佔用很多虛擬記憶體?

Question: I have a problem with a Java application running under Linux. When I launch the application, using the default maximum heap size (64mb), I s