Out of memory: Kill process 2249 (nginx) score 1 or sacrifice child

leixue0906發表於2016-02-17
轉載於:http://gm100861.blog.51cto.com/1930562/922664
原創作品,允許轉載,轉載時請務必以超連結形式標明文章 原始出處 、作者資訊和本宣告。否則將追究法律責任。http://gm100861.blog.51cto.com/1930562/922664

環境:

Ubuntu Server 12.04  i686

問題描述:

	
	
  1. 24G記憶體,空閒的有20G左右。但是核心老是報這個,動不動就殺程式 
  2.  
  3. Jul  6 13:12:44 00098 kernel: [3112325.883069] Out of memory: Kill process 2249 (nginx) score 1 or sacrifice child 
  4. Jul  6 13:12:44 00098 kernel: [3112325.922795] Killed process 2831 (nginx) total-vm:21772kB, anon-rss:11048kB, file-rss:916kB 
  5.  
  6. Jul  6 12:43:18 00098 kernel: [3110562.214498] snmpd invoked oom-killer: gfp_mask=0x840d0order=0oom_adj=0oom_score_adj=0 
  7. Jul  6 12:43:18 00098 kernel: [3110562.214502] snmpd cpuset=/ mems_allowed=0 
  8.  
  9. Jul  6 12:49:57 00098 kernel: [3110960.995962] Out of memory: Kill process 1858 (mysqld) score 1 or sacrifice child 
  10. Jul  6 12:49:57 00098 kernel: [3110961.032675] Killed process 1858 (mysqld) total-vm:140652kB, anon-rss:15492kB, file-rss:6100kB 
  11. Jul  6 12:49:57 00098 kernel: [3110961.103870] init: mysql main process (1858) killed by KILL signal 
  12. Jul  6 12:49:57 00098 kernel: [3110961.103899] init: mysql main process ended, respawning 


 真的是很鬱悶啊,搭建了一個Cacti,系統上剛好有Nginx,所以就用了Nginx,要提供php的支援,還必須安裝php5-fpm,安裝完成後,登陸上Cacti,過一會兒一重新整理,就掛掉了,剛開始還以為是Nginx掛掉了,就沒在意,過一會兒,監控報警說Nginx掛掉了,看了下Nginx的日誌,沒發現異常,今天又發現MySQL掛了,這下蛋疼了,怎麼程式動不動就掛呢!仔細分析了一下日誌,發現核心報了以上內容,OOM-KILLER這個東西,動不動就殺程式,但是記憶體並沒有滿,空的很。

然後網上找了下資料,32位的系統,如果Low-memory耗盡,就會導致這個問題的出現。看了一下Low-memory,確實很少!


通常,在大記憶體(6Gb+)伺服器上,out of memory killer (oom-killer)也會殺死程式。在很多case中,人們都困惑地報告說還有剩餘記憶體的情況下,為何oom-killer還會殺死程式?現象是在 /var/log/messages 日誌中,有如下資訊:


  Out of Memory: Killed process [PID] [process name].

在我自己的case中,我在VMware中升級了各個RHEL3到RHEL4,有1個16Gb記憶體的伺服器,還是會被oom-killer殺死程式。不用說,這非常令人沮喪。


事實證明,這個問題的原因是low memory耗盡。引用Tom的話“核心使用low memory來跟蹤所有的記憶體分配,這樣的話一個16GB記憶體的系統比一個4GB記憶體的系統,需要消耗更多的low memory,可能有4倍之多。這種額外的壓力從你剛啟動系統那一刻就開始存在了,因為核心結構必須為潛在的跟蹤四倍多的記憶體分配而調整大小


說白了 OOM Killer 就是一層保護機制,用於避免 Linux 在記憶體不足的時候不至於出太嚴重的問題,把無關緊要的程式殺掉,有些壯士斷腕的意思。

先要學習點老知識,在 32 位CPU 架構下定址是有限制的。Linux 核心定義了三個區域:


	
	
  1. # DMA: 0x00000000 -  0x00999999 (0 - 16 MB) 
  2.  
  3. # LowMem: 0x01000000 - 0x037999999 (16 - 896 MB) - size: 880MB 
  4.  
  5. # HighMem: 0x038000000 - <硬體特定> 

LowMem 區 (也叫 NORMAL ZONE ) 一共 880 MB,而且不能改變(除非用 hugemem 核心)。對於高負載的系統,就可能因為 LowMem 利用不好而引發 OOM Killer 。一個可能原因是 LowFree 太少了,另外一個原因是 LowMem 裡都是碎片,請求不到連續的記憶體區域



有兩種方法檢視 low memory 和 high memory 的狀態:


	
	
  1. # egrep 'High|Low' /proc/meminfo 
  2. HighTotal:     5111780 kB 
  3. HighFree:         1172 kB 
  4. LowTotal:       795688 kB 
  5. LowFree:         16788 kB 
  6.  
  7. # free -lm 
  8.              total       used       free     shared    buffers     cached 
  9. Mem:          5769       5751         17          0          8       5267 
  10. Low:           777        760         16          0          0          0 
  11. High:         4991       4990          1          0          0          0 
  12. -/+ buffers/cache:        475       5293 
  13. Swap:         4773          0       4773 
當low memory耗盡,不管high memory剩餘多少,oom-killer都開始殺死程式,以保持系統的正常運轉。


有兩種方法可以解決這個問題


1、如果可能,請升級到64位系統。

這是最好的解決辦法,因為所有的記憶體都將成為low memory。如果你在這種情況下耗盡了low memory,那就真的是out of memory了。

2、如果受限於必須使用32位系統,最好的解決辦法是使用hugemem核心。

這種核心以不同的方式分割low/high memory,而且在大多數情況下會提供足夠多的low memory到high memory的對映。在大多數案例中,這是一個很簡單的修復方法:安裝hugemem kernel RPM包,然後重啟即可。

如果執行hugemem核心也不可能,你可以嘗試將/proc/sys/vm/lower_zone_protection 的值設定為250甚至更多。這將讓核心願意保護low memory,從而在分配記憶體時多考慮從high memory分配。據我所知,此選項從2.6.x核心才開始可用。必要的是,您可能需要透過一些實驗來找到您系統環境中最適合的值。可以使用下面方法快速的設定和檢查改值:


	
	
  1. # cat /proc/sys/vm/lower_zone_protection 
  2. # echo "250" > /proc/sys/vm/lower_zone_protection 


在 /etc/sysctl.conf 中加入設定,以便啟動就生效:

  vm.lower_zone_protection = 250



作為最後的努力,你可以關閉oom-killer。這個選項可以導致系統掛起,所以請小心使用(風險自負)!

檢視當前oom-killer的狀態:


	
	
  1. # cat /proc/sys/vm/oom-kill 

關閉/開啟oom-killer:


	
	
  1. # echo "0" > /proc/sys/vm/oom-kill 
  2. # echo "1" > /proc/sys/vm/oom-kill 



當程式該被oom-killer殺死卻沒有被殺死時,相關資訊會記錄到 /var/log/messages:

"Would have oom-killed but /proc/sys/vm/oom-kill is disabled"





來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/26845409/viewspace-1990239/,如需轉載,請註明出處,否則將追究法律責任。

相關文章