1) Kernel真的內存耗盡了./proc/meminfo中的SwapFree和MemFree很低.都小於1%,那麼負載過大就是緣由.php
2) 若是LowFree很低而HighFree高不少,那麼就是32位體系結構的緣由,若是在64位內核或平臺上就會好不少.html
3) 內核數據結構或者內存泄漏.java
/proc/slabinfo佔用最多空間的對象是什麼對象?awk '{printf "%5d MB %s\n", $3*$4/(1024*1024), $1}' < /proc/slabinfo | sort -n,
若是一種對象佔用了系統的大部份內存,那麼就有多是這個對象的緣由.檢查這個對象的子系統.linux
SwapFree和MemFree的大小?算法
task_struct對象的數字是多少?是不是由於系統fork了太多進程致使的.數據庫
4)內核沒有正確使用swap分區.tomcat
若是應用程序使用了mlock()或者Huge TLBfs pages,那麼有可能這個應用程序就不能使用swap空間.這種狀況下,Swap Free很高仍然會OOM.mlock和Huge TLBfs pages這兩個特徵不容許系統將使用的內存換出,所以,這樣過分使用內存會使得系統內存耗盡而讓系統沒有其餘資源.服務器
也有多是系統本身有死鎖.將數據寫入磁盤也須要爲各類各樣的IP數據結構開闢內存.若是系統根本找不到這樣的內存,正是用來產生空閒內存的函數會致使系統內存耗盡.可使用一些小的調節方法好比較早的頁映射機智,可是若是系統不能快速的將髒頁面換出來釋放內存,咱們只能說負載過大而沒有辦法解決.增長/proc/sys/vm/min_free_kbytes會使得系統回收內存更早.這也會使得系統更難進入死鎖.若是你的系統時由於死鎖而致使OOM那麼這是一個很好的調節值.網絡
5)內核做出了錯誤的決定,讀數據錯誤.當它還有很大RAM的時候就OOM了.數據結構
6)一些病理性的事情發生了.當內核花了一段很長的時間去掃描內存來釋放.2.6.19版本的內核中,這個很長的時間指的就是VM掃描了和同一區域的active+inactive 頁面6倍長的時間後.
若是內核正在快速掃描頁,而你的IO設備(swap,filesystem,network fs)太慢了,內核會判定沒有進程在進行交換而觸發一次OOM即便swap有空閒.
解決方法:
1 2 3 |
|
lowMem也叫Normal Zone區,是固定不能變的,若是lowMem裏存在不少碎片會觸發OOM killer.
察看目前系統的LowMem使用情況:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
可使用的解決方案:
a 添加swap分區。
b 升級64位系統
c 若是必須使用32位系統,可使用hugemem內核,此時內核會以不一樣的方式分割low/high memory,而大多狀況提供足夠多的low memory至high memory的映射。
d 將/proc/sys/vm/lower_zone_protection的值設爲250或更大。或者修改/etc/sysctl.conf vm.lower_zone_protection這將會使內核在可以在high memory中分配內存時,不會再low zone裏面開闢.
e 關掉 oom-kill echo "0" > /proc/sys/vm/oom-kill 或者修改:/etc/sysctl.conf vm.oom-kill = 0 (此方法不建議,系統會變得更糟糕)
f 增大內存
g 保護單個進程 echo -17 > /proc/[pid]/oom_adj
-------------------以上盜自http://iblog.daobidao.com/linux-linux-system-oom-killer-out-of-memory-killer-approach.DaoBiDao---------------------------------------------------------------------------
然而我遇到的問題是:
tail -n 2 /var/log/message
顯示的結果:
May 19 23:33:08 iZ2879ng6hoZ kernel: Out of memory: Kill process 2339 (java) score 134 or sacrifice child
May 19 23:33:08 iZ2879ng6hoZ kernel: Killed process 2339, UID 0, (java) total-vm:3248664kB, anon-rss:314076kB, file-rss:280kB
-------------------如下盜自http://it.deepinmind.com/java/2014/06/12/out-of-memory-kill-process-or-sacrifice-child.html--------------------------------------------------------
很明顯咱們被Linux內核給坑了。你知道的,Linux裏面有許多邪惡的怪物(也叫做守護進程)。這些守護進程是由幾個內核做業所看管的,其中的一個猶爲惡毒。全部的現代Linux內核中都會有一個內存不足終結者(Out of memory Killer, OOM Killer)的內建機制,在內存太低的狀況下,它會殺掉你的進程。當探測到這一狀況時,這個終結者會被激活,而後挑選出一個進程去終結掉。選擇目標進程使用的是一套啓發式算法,它會計算全部進程的分數,而後選出那個分數最低的進程。
默認狀況下,Linux內核會容許進程請求的內存超出實際可用內存的大小。這在現實世界中是有意義的,由於大多數進程其實並不會用到全部分配給它的內存(注:同一時間內不會全用到)。和這個問題最相似的就是運營商了。他們承諾賣給用戶的都是100Mb的帶寬,這實際上遠遠超出了他們的網絡容量。他們賭的就是用戶實際上並不會同時用完分配給他們的下載上限。一個10Gb的鏈接能夠很輕鬆地承載100個以上的用戶,這裏的100是經過簡單的數學運算得出的(10G/100M)。
這個作法的一個很明顯的反作用就是,萬一有一個程序正走上了一條耗盡內存的不歸路怎麼辦。這會致使低可用內存的狀況,也就是沒有內存頁可以再分配給進程了。你可能也碰到過這種狀況,沒有root賬戶你是殺不掉這種頑固的進程的。爲了解決這一狀況,終結者被激活了,並找出了要終結的進程。
關於"Out of memory killer"參數的調整,能夠參考下這篇文章。
=========================================================================
機器狀況:2g內存同時有運行tomcat網站也有php的論壇和博客,數據庫也搭在同一臺服務器(窮啊)
運行狀況:經過查進程發現有大量的php-fpm進程在運行,然而並無這麼多訪問。查看php-fpm配置發現啓動就有大量的進程 佔用不少內存
解決方案:修改php-fpm配置歸還內存空間