Linux

Linux メモリ不足で発生するOOM Killerによるプロセスの突然死の確認&回避方法

*記事内に商品プロモーションを含む場合があります

Linux メモリ不足で発生するOOM Killerによるプロセスの突然死の確認方法、および、回避方法を紹介します。

Linuxでプロセスが突然いなくなる場合、OOM Killerが原因の場合が多いです。

OOM Killerとは

Linux OSは、メモリが不足してOSが停止する恐れがある場合、メモリを多く消費しているプロセスを強制的に殺します。これをOOM Killerといいます。重要なプロセスでも殺します。(Kill)

OOM Killer(Out of Memory Killer)は、システムが実メモリとスワップ領域を使い切り、必要なメモリ領域を新たに確保できない場合にプロセスを強制終了させて空きメモリを確保するLinuxカーネルの仕組みです。

OOM Killerは、空きメモリが確保できないことによりOS自体が停止するという最悪の事態を避けるために用意されています。

OOM Killerの確認方法(ログを確認する)

OOM Killer発生時は、Linuxシステムのログファイルに出力されます。

sudo grep -i kill /var/log/messages*

/var/log/messages を見るにはroot権限が必要です。

Out of memory」と出力されています。

$
$

$ sudo grep -i kill /var/log/messages*

May 10 18:07:27 server1 kernel: Out of memory: Kill process 202647 (program01) score 982 or sacrifice child

OOMKillerの原因はプロセスがメモリを使いすぎ

OOMKillerは、プロセスがOSが確保できるメモリ上限まで使ってしまうことで原因です。

a)特定のプロセスが大量にメモリを使用した場合

b)いろいろなプロセスがメモリを使って全体でメモリが不足した場合

個々のアプリの設定で利用メモリを抑制する必要があります。

OOMKillerでプロセス停止を抑制

基本的には、メモリ不足なので各プロセスが使うメモリ量を調整(サイジング)することが正しい対処方法です。

もしくは物理メモリの追加。

メモリの使用量が多いプロセス=重要なプロセスが停止させられるので厄介です。

Webサーバ(httpd,nginx,…)やデータベース(Mysql,postgreSQL,..)など。

systemd(systemctl)を使って起動しているサービスの対応

nginxで説明します。

Mysql なら nginx が、mysqld に
httpd なら nginx が、httpd に代わるだけで同じ方法で対応可能です。

(1)サービスのstatusを確認

$
$

$ sudo systemctl status nginx
● nginx.service - A high performance web server and a reverse proxy server
     Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
     Active: active (running) since Sat 2022-12-31 09:17:23 UTC; 2s ago
       Docs: man:nginx(8)
    Process: 9609 ExecStartPre=/usr/sbin/nginx -t -q -g daemon on; master_process on; (code=exited, status=0/SUCCESS)
    Process: 9610 ExecStart=/usr/sbin/nginx -g daemon on; master_process on; (code=exited, status=0/SUCCESS)
   Main PID: 9611 (nginx)
 ...

(2)ディレクトリを作成 「サービス名.service.d」ディレクトリ

$

$ sudo mkdir /etc/systemd/system/nginx.service.d

(3)override.confファイルを作成

$

$ sudo  vi /etc/systemd/system/nginx.service.d/override.conf

[Service]
OOMScoreAdjust=-1000
...

(4)設定を読み込み

$
$ sudo systemctl daemon-reload

★サービスを再起動
$ sudo systemctl restart nginx.service

(5)statusを確認。作成したファイルが読み込まれていることを確認します。

$
$  sudo systemctl status nginx
● nginx.service - A high performance web server and a reverse proxy server
     Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
    Drop-In: /etc/systemd/system/nginx.service.d
             |-override.conf  ★作成したファイルが読み込まれている★
     Active: active (running) since Sat 2022-12-31 09:21:35 UTC; 3s ago
       Docs: man:nginx(8)
    Process: 9688 ExecStartPre=/usr/sbin/nginx -t -q -g daemon on; master_process on; (code=exited, status=0/SUCCESS)
    Process: 9690 ExecStart=/usr/sbin/nginx -g daemon on; master_process on; (code=exited, status=0/SUCCESS)
   Main PID: 9691 (nginx)
 ...

(6)プロセスIDのディレクトリの状態ファイルを確認する。-1000になっている。

$
$ cat /proc/9691/oom_score_adj 
-1000

$ dstat --top-oom

CentOS系(Red Hat系)は  dstatに –top-oom オプションが存在しないかも。

スワップ領域を増やす

一時的なメモリ不足による問題であれば、スワップファイル(swap file)を作成して回避する方法もあります。

慢性的なメモリ不足の場合は、プロセスの使用メモリを減らすか、物理メモリを増やすべきです。

最後に

OOMKillerはLinux独自機能で、Windowsにはありません。

Windowsのプロセスだとメモリが確保できずに、プロセス内でエラーが発生するだけです。