OOM Killer ( 2 )

February 12, 2020

Swap を有効化した環境における OOM

一般的に Swap を有効化した環境ではそうでない環境よりも OOM Killer が invoke される頻度は減ものの、それでもプロセスが要求するメモリ量を Swap で賄えなくなった場合は OOM によりプロセスが Kill される。
実際に挙動を確認するため、以下のようなコードで検証を実施してみる。

#include <unistd.h>  
#include <time.h>  
#include <stdio.h>  
#include <stdlib.h>  
#include <string.h>  
#include <err.h>  
  
#define BUFFER_SIZE (2000*1024*1024)  
#define NCYCLE 30  
#define PAGE_SIZE 4096  
    
int main(void) {  
  char *p;  
    
  pid_t pid;  
  pid = getpid();  
    
  char pidStr[12];  
  snprintf(pidStr, 12, "%d", pid);  
  char str1[] = "echo -17 > /proc/";  
  char str2[] = "/oom_adj";  
  
  char *command_tmp;  
  char *command;  
  command_tmp = strcat(str1, pidStr);  
  command = strcat(command_tmp, str2);  
  
  system(command);  
    
  p = malloc(BUFFER_SIZE);  
  if (p == NULL)  
    err(EXIT_FAILURE, "malloc() failed.");  
    
  int i;  
  for (i = 0; i < BUFFER_SIZE; i += PAGE_SIZE) {  
    p[i] = 0;  
    int cycle = i / (BUFFER_SIZE/NCYCLE);  
    if (cycle != 0 &amp;&amp; i % (BUFFER_SIZE/NCYCLE) == 0) {  
      sleep(1);  
    }  
  }  
    
  exit(EXIT_SUCCESS);  
}  

上記コードでは 2 GB 分の仮想メモリ領域を確保し、その領域に実際にアクセスすることで、物理メモリ領域を圧迫する。
また、自身の PID を取得し、/proc/[PID]/oom_adj に -17 を書き込むことにより、このプロセスが OOM Killer により kill されないようにしている。

なお、試す場合はオーバーコミットポリシーを OVERCOMMIT_ALWAYS にしておき、システムのメモリ量を大幅に超えても仮想メモリ領域を確保できるようにする必要がある。ちなみに今回は 1 GB のメモリを搭載したホストで検証を行う。

$ sudo bash -c "echo 1 > /proc/sys/vm/overcommit_memory"  
$ cat /proc/sys/vm/overcommit_memory  
1  
$ free  
             total       used       free     shared    buffers     cached  
Mem:       1009432     267876     741556         64      21440     170396  
-/+ buffers/cache:      76040     933392  
Swap:       524284          0     524284  

Swap 領域は 500 MB ほど。

$ swapon -s  
Filename				Type		Size	Used	Priority  
/swapfile                              	file	524284	0	-2  

では早速コンパイルしてバックグラウンドで実行する (バックグラウンドで実行しないと SSH のセッションが切られてプロセスが終了するため)。

$ gcc -o oom oom.c   
$ sudo ./oom &amp;  
[1] 24423  

上記を実行するとこちらからの入力を一切受け付けなくなり、セッションが切断される様子が確認できる。

Connection to 52.26.127.65 closed by remote host.  
Connection to 52.26.127.65 closed.  

結果

コンソール出力を見てみると、OOM Killer が invoke されていることがわかる。また、Swap cache stats から Free swap が 0kB であることも併せて確認可能。
なお、その後 killable なプロセスが無くなってシステムは再起動した。

[43373.298270] oom invoked oom-killer: gfp_mask=0x14201ca(GFP_HIGHUSER_MOVABLE|__GFP_COLD), nodemask=(null),  order=0, oom_score_adj=-1000  
[43373.308932] oom cpuset=/ mems_allowed=0  
  
...  
  
[43373.712031] Swap cache stats: add 137282, delete 137231, find 352/836  
[43373.719424] Free swap  = 0kB  
[43373.723246] Total swap = 524284kB  
[43373.727479] 262045 pages RAM  
[43373.731361] 0 pages HighMem/MovableOnly  
[43373.737251] 9687 pages reserved  
[43373.741326] [ pid ]   uid  tgid total_vm      rss nr_ptes nr_pmds swapents oom_score_adj name  
[43373.751339] [ 1580]     0  1580     2880        1      12       3      233         -1000 udevd  
[43373.761851] [ 2250]     0  2250    13252        0      26       3      106         -1000 auditd  
[43373.771828] [ 2530]     0  2530    20148        4      41       3      204         -1000 sshd  
[43373.783899] [ 2619]     0  2619     1628        1       8       3       30             0 agetty  
[43373.797922] [ 2622]     0  2622     1091        1       8       3       23             0 mingetty  
[43373.808510] [ 2626]     0  2626     1091        1       8       3       23             0 mingetty  
[43373.824982] [ 2628]     0  2628     1091        1       8       3       23             0 mingetty  
[43373.847313] [ 2630]     0  2630     1091        1       8       3       24             0 mingetty  
[43373.873998] [ 2632]     0  2632     1091        1       8       3       24             0 mingetty  
[43373.886506] [ 2634]     0  2634     1091        1       7       3       23             0 mingetty  
[43373.900702] [ 2637]     0  2637     2879        1      11       3      233         -1000 udevd  
[43373.909388] [23247]     0 23247     2879        1      11       3      232         -1000 udevd  
[43373.919122] [24424]     0 24424   513056   231718     715       5   130284         -1000 oom  
[43373.927345] Out of memory: Kill process 2619 (agetty) score 0 or sacrifice child  
[43373.939239] Killed process 2619 (agetty) total-vm:6512kB, anon-rss:0kB, file-rss:4kB, shmem-rss:0kB  

なお、SwapIn/Out の大量発生により、Disk に対する IOPS も高騰している点が確認できる。
これが Swap が有効化されていない環境と比較した時の大きな違いとなる。

f:id:shiro_kochi:2018××××××××:plain:w100:left


 © 2023, Dealing with Ambiguity