linux 终端报错 Out of memory: Kill process[PID] [process name] score问题分析
轉(zhuǎn)自:http://www.111cn.net/sys/CentOS/84755.htm
?
從Out of memory來(lái)看是內(nèi)存超出了,后面的 Kill process[PID] [process name] score好像和進(jìn)程有關(guān)了,下面我們就一起來(lái)看看linux 終端報(bào)錯(cuò) Out of memory: Kill process[PID] [process name] score問(wèn)題分析看到屏幕上都是 Out of memory: Kill process[PID] [process name] score,雖然知道這是linux自我保護(hù)進(jìn)行內(nèi)存清理動(dòng)作,但是為了知道更多的細(xì)節(jié)進(jìn)行了學(xué)習(xí)。
【原因分析】
Out of memory 問(wèn)題,這通常是因?yàn)槟硶r(shí)刻應(yīng)用程序大量請(qǐng)求內(nèi)存導(dǎo)致系統(tǒng)內(nèi)存不足造成的,這通常會(huì)觸發(fā) Linux 內(nèi)核里的 Out of Memory (OOM) killer,OOM killer 會(huì)殺掉某個(gè)進(jìn)程以騰出內(nèi)存留給系統(tǒng)用,不致于讓系統(tǒng)立刻崩潰。
Linux 內(nèi)核根據(jù)應(yīng)用程序的要求分配內(nèi)存,通常來(lái)說(shuō)應(yīng)用程序分配了內(nèi)存但是并沒(méi)有實(shí)際全部使用,為了提高性能,這部分沒(méi)用的內(nèi)存可以留作它用,這部分內(nèi)存是屬于每個(gè)進(jìn)程的,內(nèi)核直接回收利用的話比較麻煩,所以內(nèi)核采用一種過(guò)度分配內(nèi)存(over-commit memory)的辦法來(lái)間接利用這部分 “空閑” 的內(nèi)存,提高整體內(nèi)存的使用效率。一般來(lái)說(shuō)這樣做沒(méi)有問(wèn)題,但當(dāng)大多數(shù)應(yīng)用程序都消耗完自己的內(nèi)存的時(shí)候麻煩就來(lái)了,因?yàn)檫@些應(yīng)用程序的內(nèi)存需求加起來(lái)超出了物理內(nèi)存(包括 swap)的容量,內(nèi)核(OOM killer)必須殺掉一些進(jìn)程才能騰出空間保障系統(tǒng)正常運(yùn)行。
可能有些同學(xué)發(fā)現(xiàn)內(nèi)存還剩下很多啊?怎么還是在報(bào)錯(cuò)內(nèi)存不夠呢?那是因?yàn)?2位的系統(tǒng),如果Low-memory耗盡,就會(huì)導(dǎo)致這個(gè)問(wèn)題的出現(xiàn)。那low-memory又是怎么回事呢?
內(nèi)核使用low memory來(lái)跟蹤所有的內(nèi)存分配,這樣的話一個(gè)16GB內(nèi)存的系統(tǒng)比一個(gè)4GB內(nèi)存的系統(tǒng),需要消耗更多的low memory,可能有4倍之多。這種額外的壓力從你剛啟動(dòng)系統(tǒng)那一刻就開(kāi)始存在了,因?yàn)閮?nèi)核結(jié)構(gòu)必須為潛在的跟蹤四倍多的內(nèi)存分配而調(diào)整大小
OOM Killer 就是一層保護(hù)機(jī)制,用于避免 Linux 在內(nèi)存不足的時(shí)候不至于出太嚴(yán)重的問(wèn)題,把無(wú)關(guān)緊要的進(jìn)程殺掉,有些壯士斷腕的意思。
在 32 位CPU 架構(gòu)下尋址是有限制的。Linux 內(nèi)核定義了三個(gè)區(qū)域:
# DMA: 0x00000000 -? 0x00999999 (0 - 16 MB)
# LowMem: 0x01000000 - 0x037999999 (16 - 896 MB) - size: 880MB
# HighMem: 0x038000000 - <硬件特定>
LowMem 區(qū) (也叫 NORMAL ZONE ) 一共 880 MB,而且不能改變(除非用 hugemem 內(nèi)核)。對(duì)于高負(fù)載的系統(tǒng),就可能因?yàn)?LowMem 利用不好而引發(fā) OOM Killer 。一個(gè)可能原因是 LowFree 太少了,另外一個(gè)原因是 LowMem 里都是碎片,請(qǐng)求不到連續(xù)的內(nèi)存區(qū)域。
另外,在64位系統(tǒng)下low-memory是所有的內(nèi)存空間。
查看low memory 和 high memory 的狀態(tài):
[root@localhost ~]# free -lm
???????????? total?????? used?????? free???? shared??? buffers???? cached
Mem:???????? 32105????? 11305????? 20800????????? 0??????? 176?????? 5402
Low:???????? 32105????? 11305????? 20800
High:??????????? 0????????? 0????????? 0
-/+ buffers/cache:?????? 5726????? 26379
Swap:??????? 32767????????? 0????? 32767
【OOM killer原理】
從oom_killer給每個(gè)進(jìn)程打分,根據(jù) points 的高低來(lái)決定殺哪個(gè)進(jìn)程,這個(gè)points可以調(diào)節(jié),root 權(quán)限的進(jìn)程通常被認(rèn)為很重要,不應(yīng)該被輕易殺掉,所以打分的時(shí)候可以得到 3% 的優(yōu)惠( -= 30; 分?jǐn)?shù)越低越不容易被殺掉)。我們可以在用戶空間通過(guò)操作每個(gè)進(jìn)程的內(nèi)核參數(shù)來(lái)決定哪些進(jìn)程不這么容易被 OOM killer 選中殺掉。比如,如果不想 MySQL 進(jìn)程被輕易殺掉的話可以找到 MySQL 運(yùn)行的進(jìn)程號(hào)后,調(diào)整 oom_score_adj 為 -15(注意 points 越小越不容易被殺)
ps?aux | grep mysqld
mysql??? 2196? 1.6? 2.1 623800 44876 ???????? Ssl? 09:42?? 0:00 /usr/sbin/mysqld
?
cat /proc/2196/oom_score_adj
0
echo -15 > /proc/2196/oom_score_adj
【解決方法】
知道了原理,那么怎么解決呢?
一、增大內(nèi)存。
內(nèi)存不夠咱們肯定要增加啊?不然怎么叫服務(wù)器呢?
二、升級(jí)到64位操作系統(tǒng)。
64位的操作系統(tǒng)沒(méi)有對(duì)low-memory限制。
三、使用hugemem內(nèi)核。
這種內(nèi)核以不同的方式分割low/high memory,而且在大多數(shù)情況下會(huì)提供足夠多的low memory到high memory的映射。在大多數(shù)案例中,這是一個(gè)很簡(jiǎn)單的修復(fù)方法:安裝hugemem kernel RPM包,然后重啟即可。
四、配置 OOM killer
通過(guò)一些內(nèi)核參數(shù)來(lái)調(diào)整 OOM killer 的行為,避免系統(tǒng)在那里不停的殺進(jìn)程。比如我們可以在觸發(fā) OOM 后立刻觸發(fā) kernel panic,kernel panic 10秒后自動(dòng)重啟系統(tǒng)。
echo "vm.panic_on_oom=1" >> /etc/sysctl.conf
echo "kernel.panic=10" >> /etc/sysctl.conf
sysctl -p
五、關(guān)閉/打開(kāi)oom-killer(慎用)
echo "0" > /proc/sys/vm/oom-kill
echo "1" > /proc/sys/vm/oom-kill
總結(jié)
以上是生活随笔為你收集整理的linux 终端报错 Out of memory: Kill process[PID] [process name] score问题分析的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: [译]震惊!RxJava 5 个不为人知
- 下一篇: Spring点滴二:Spring Bea