OOMキラー値は常に​​設定値より1小さい

OOMキラー値は常に​​設定値より1小さい

メモリ不足キラーの値を設定しようとしていますoom_adjが、設定するたびに (プロセスに関係なく) 設定した値より 1 少ない値が返されます (少なくとも正の整数の場合。これらのプロセスはまず OOM キラーによって強制終了される必要があるため、負の整数は試していません)。

[root@server ~]# echo 10 > /proc/12581/oom_adj
[root@server ~]# cat /proc/12581/oom_adj
9
[root@server ~]# echo 9 > /proc/12581/oom_adj
[root@server ~]# cat /proc/12581/oom_adj
8
[root@server ~]# echo 8 > /proc/12581/oom_adj
[root@server ~]# cat /proc/12581/oom_adj
7
[root@server ~]# echo 7 > /proc/12581/oom_adj
[root@server ~]# cat /proc/12581/oom_adj
6
[root@server ~]# 

これは想定された動作ですか? そうでない場合、なぜこのようなことが起こるのでしょうか?

答え1

oom_adjは非推奨であり、レガシー目的でのみ提供されています。Linux は内部的に、oom_score_adjより広い範囲を持つ を使用します。oom_adj最大 15 ですが、oom_score_adj最大 1000 です。

oom_adj(たとえば 9に)書き込むたびに、カーネルは次の処理を実行します。

oom_adj = (oom_adj * OOM_SCORE_ADJ_MAX) / -OOM_DISABLE;

それを に格納しますoom_score_adjOOM_SCORE_ADJ_MAXは 1000 で、OOM_DISABLE-17 です。

したがって、9 の場合はoom_adj=(9 * 1000) / 17 ~= 529.411、これらの値は整数なので、oom_score_adj529 が保持されます。

oom_adjカーネルを読み込むと、次の処理が実行されます。

oom_adj = (task->signal->oom_score_adj * -OOM_DISABLE) / OOM_SCORE_ADJ_MAX;

したがって、529 の場合は次のようになります。oom_adj = (529 * 17) / 1000 = 8.993カーネルは整数と整数演算を使用しているため、これは 8 になります。

つまり、固定小数点/整数演算により、9 と書くと 8 になります。

関連情報