Linux核心引數overcommit_memory和OOM killer介紹

chenfeng發表於2019-03-13

什麼是Linux Overcommit和OOM

overcommit_memory是一個核心對記憶體分配的一種策略,它有三個可選值:0、1、2。


0. 表示核心將檢查是否有足夠的可用記憶體供應用程式使用;如果有足夠的可用記憶體,記憶體申請允許;否則,記憶體申請失敗,

並把錯誤返回給應用程式。

1. 表示核心允許分配所有的實體記憶體,而不管當前的記憶體狀態如何。

2. 表示核心允許分配超過所有實體記憶體和交換空間總和的記憶體。


Linux對大部分申請記憶體的請求都回復"yes",以便能跑更多更大的程式。因為申請記憶體後,並不會馬上使用記憶體。

這種技術叫做 Overcommit。

當linux發現記憶體不足時,會發生OOM killer(OOM=out-of-memory)。它會選擇殺死一些程式

(使用者態程式,不是核心執行緒),以便釋放記憶體。

例如Linux下發現有如下報錯資訊,則說明系統發生了OOM killer

# dmesg | grep redis | grep "oom-killer"

redis-server invoked oom-killer: gfp_mask=0x280da, order=0, oom_adj=0, oom_score_adj=0

redis-server invoked oom-killer: gfp_mask=0x200da, order=0, oom_adj=0, oom_score_adj=0

redis-server invoked oom-killer: gfp_mask=0x200da, order=0, oom_adj=0, oom_score_adj=0

redis-server invoked oom-killer: gfp_mask=0x200da, order=0, oom_adj=0, oom_score_adj=0

redis-server invoked oom-killer: gfp_mask=0x280da, order=0, oom_adj=0, oom_score_adj=0

redis-server invoked oom-killer: gfp_mask=0x200da, order=0, oom_adj=0, oom_score_adj=0

redis-server invoked oom-killer: gfp_mask=0x200da, order=0, oom_adj=0, oom_score_adj=0

redis-server invoked oom-killer: gfp_mask=0xd0, order=0, oom_adj=0, oom_score_adj=0

redis-server invoked oom-killer: gfp_mask=0x280da, order=0, oom_adj=0, oom_score_adj=0

redis-server invoked oom-killer: gfp_mask=0x280da, order=0, oom_adj=0, oom_score_adj=0

redis-server invoked oom-killer: gfp_mask=0xd0, order=0, oom_adj=0, oom_score_adj=0

redis-server invoked oom-killer: gfp_mask=0x280da, order=0, oom_adj=0, oom_score_adj=0

redis-server invoked oom-killer: gfp_mask=0xd0, order=0, oom_adj=0, oom_score_adj=0

redis-server invoked oom-killer: gfp_mask=0xd0, order=0, oom_adj=0, oom_score_adj=0

redis-server invoked oom-killer: gfp_mask=0x201da, order=0, oom_adj=0, oom_score_adj=0

redis-server invoked oom-killer: gfp_mask=0xd0, order=0, oom_adj=0, oom_score_adj=0

redis-server invoked oom-killer: gfp_mask=0x280da, order=0, oom_adj=0, oom_score_adj=0



當oom-killer發生時,linux會選擇殺死該程式,例如:

Out of memory: Kill process 21809 (redis-server) score 951 or sacrifice child

Killed process 21809, UID 0, (redis-server) total-vm:33466920kB, anon-rss:32324096kB, file-rss:100kB


具體殺死哪個程式取決於選擇程式的函式,選擇程式的函式是oom_badness函式(在mm/oom_kill.c中),該函式

會計算每個程式的點數(0~1000)。

點數越高,這個程式越有可能被殺死。每個程式的點數跟oom_score_adj有關,而且 oom_score_adj可以被

設定(-1000最低,1000最高)。


理解memory overcommit的關鍵:commit(或overcommit)針對的是記憶體申請,記憶體申請不等於記憶體分配,記憶體

只在實際用到的時候才分配。


備註:

如何修改Linux vm.overcommit_memory的值,可用的方法有以下三種:


1).以root身份登入Linux,編輯/etc/sysctl.conf ,改vm.overcommit_memory=1,然後sysctl -p使配置檔案生效

2).sysctl vm.overcommit_memory=1

3).echo 1 > /proc/sys/vm/overcommit_memory


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

相關文章