系統(tǒng)之家 - 系統(tǒng)光盤下載網(wǎng)站!

當(dāng)前位置:系統(tǒng)之家 > 系統(tǒng)教程 > Linux OOM killer 機(jī)制

Linux如何使用OOM killer 機(jī)制?(2)

時(shí)間:2015-08-06 11:44:48 作者:zhijie 來源:系統(tǒng)之家 1. 掃描二維碼隨時(shí)看資訊 2. 請使用手機(jī)瀏覽器訪問: https://m.xitongzhijia.net/xtjc/20150806/54848.html 手機(jī)查看 評論

  OOM Killer計(jì)算分?jǐn)?shù)

  1. 首先,計(jì)算分?jǐn)?shù)時(shí)是以進(jìn)程的虛擬內(nèi)存大小為基準(zhǔn)的,虛擬內(nèi)存大小可以使用ps命令的VSZ或/proc/《PID》/status的 VmSize來確認(rèn)。對于正在消耗虛擬內(nèi)存的進(jìn)程,其最初的得分較高,單位是將1KB作為1個(gè)得分,消耗1GB內(nèi)存的進(jìn)程,得分約為1024*1024。

  2.如果進(jìn)程正在執(zhí)行swapoff系統(tǒng)調(diào)用,則得分設(shè)置為最大值(unsigned long的最大值)。這是因?yàn)榻胹wap的行為與消除內(nèi)存不足是相反的,會立刻將其作為OOM Killer的對象進(jìn)程。

  3.如果是母進(jìn)程,則將所有子進(jìn)程內(nèi)存大小的一半作為分?jǐn)?shù)。

  4. 根據(jù)進(jìn)程的CPU使用時(shí)間和進(jìn)程啟動時(shí)間調(diào)整得分,這是因?yàn)樵谶@里認(rèn)為越是長時(shí)間運(yùn)行或從事越多工作的進(jìn)程越重要,需保持得分較低。

  5.對于通過nice命令等將優(yōu)先級設(shè)置得較低的進(jìn)程,要將得分翻倍。nice-n中設(shè)置為1~19的命令的得分翻倍。

  6.特權(quán)進(jìn)程普遍較為重要,因此將其得分設(shè)置為1/4。

  7.通過capset(3)等設(shè)置了功能(capability)CAP_SYS_RAWIO注3的進(jìn)程,其得分為1/4,將直接對硬件進(jìn)行操作的進(jìn)程判斷為重要進(jìn)程。

  8.關(guān)于Cgroup,如果進(jìn)程只允許與促使OOM Killer運(yùn)行的進(jìn)程所允許的內(nèi)存節(jié)點(diǎn)完全不同的內(nèi)存節(jié)點(diǎn),則其得分為1/8。

  9.最后通過proc文件系統(tǒng)oom_adj的值調(diào)整得分。

  依據(jù)以上規(guī)則,為所有進(jìn)程打分,向得分最高的進(jìn)程發(fā)送信號SIGKILL(到Linux 2.6.10為止,在設(shè)置了功能CAP_SYS_RAWIO的情況下,發(fā)送SIGTERM,在沒有設(shè)置的情況下,發(fā)送SIGKILL)。

  各進(jìn)程的得分可以使用/proc/《PID》/oom_score來確認(rèn)。

  但是init(PID為1的)進(jìn)程不能成為OOM Killer的對象。當(dāng)成為對象的進(jìn)程包含子進(jìn)程時(shí),先向其子進(jìn)程發(fā)送信號。

  向成為對象的進(jìn)程發(fā)送信號后,對于引用系統(tǒng)的全線程,即使線程組(TGID)不同,如果存在與對象進(jìn)程共享相同內(nèi)存空間的進(jìn)程,則也向這些進(jìn)程發(fā)送信號。

  至于為什么用-17而不用其他數(shù)值(默認(rèn)值為0),這個(gè)是由linux內(nèi)核定義的,查看內(nèi)核源碼可知:

  以linux- 3.3.6版本的kernel源碼為例,路徑為linux-3.6.6/include/linux/oom.h,閱讀內(nèi)核源碼可知oom_adj的可調(diào) 值為15到-16,其中15最大-16最小,-17為禁止使用OOM。oom_score為2的n次方計(jì)算出來的,其中n就是進(jìn)程的oom_adj值,所 以oom_score的分?jǐn)?shù)越高就越會被內(nèi)核優(yōu)先殺掉。

  當(dāng)然還可以通過修改內(nèi)核參數(shù)禁止OOM機(jī)制

  # sysctl -w vm.panic_on_oom=1

  vm.panic_on_oom = 1 //1表示關(guān)閉,默認(rèn)為0表示開啟OOM

  # sysctl -p

  測試程序

  命令行參數(shù)輸入占用內(nèi)存大小N,根據(jù)自身實(shí)驗(yàn)環(huán)境的物理內(nèi)存大小來設(shè)置,例如我的實(shí)驗(yàn)環(huán)境為內(nèi)存4G,設(shè)為4G就足夠了

  代碼命名為mem.c,編譯方法 gcc -o mem mem.c

  #include 《stdio.h》

  #include 《stdlib.h》

  #include 《string.h》

  #define PAGE_SZ (1《《12)

  int main(int argc, char* argv[]) {

  int i;

  if (argc != 2) return 0;

  int gb = atoi(argv[1]);

  for (i = 0; i 《 ((unsigned long)gb《《30)/PAGE_SZ ; ++i) {

  void *m = malloc(PAGE_SZ);

  if (!m)

  break;

  memset(m, 0, 1);

  }

  printf(“allocated %lu MB\n”, ((unsigned long)i*PAGE_SZ)》》20);

  getchar();

  return 0;

  }

  然后執(zhí)行 。/mem 4

  如果不執(zhí)行任何操作的話,直接運(yùn)行結(jié)果會發(fā)現(xiàn)系統(tǒng)自動oom掉這個(gè)進(jìn)程

  如果我們進(jìn)行以下操作,把進(jìn)程優(yōu)先級設(shè)置為-17

  pgrep -f “mem” | while read PID; do echo -17 》 /proc/$PID/oom_adj;done

  你會發(fā)現(xiàn)系統(tǒng)不會把這個(gè)占用大內(nèi)存的進(jìn)程oom掉,但這時(shí)你也會發(fā)現(xiàn)系統(tǒng)響應(yīng)變慢甚至宕機(jī)!

  設(shè)置任意進(jìn)程觸發(fā)oom

  一個(gè)最簡單的測試觸發(fā)OOM的方法,可以把某個(gè)進(jìn)程的oom_adj設(shè)置到15(最大值),最容易觸發(fā)。然后執(zhí)行以下命令:

  echo f 》 /proc/sysrq-trigger

  以上就是Linux如何使用OOM killer 機(jī)制,Linux強(qiáng)制殺死進(jìn)程就不會出現(xiàn)死機(jī)或者中毒的現(xiàn)象,這是Linux一大優(yōu)點(diǎn)。

標(biāo)簽 進(jìn)程

發(fā)表評論

0

沒有更多評論了

評論就這些咯,讓大家也知道你的獨(dú)特見解

立即評論

以上留言僅代表用戶個(gè)人觀點(diǎn),不代表系統(tǒng)之家立場

其他版本軟件

熱門教程

人氣教程排行

Linux系統(tǒng)推薦

掃碼關(guān)注
掃碼關(guān)注

掃碼關(guān)注 官方交流群 軟件收錄