メモリ不足キラーの値を設定しようとしています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_adj
。OOM_SCORE_ADJ_MAX
は 1000 で、OOM_DISABLE
-17 です。
したがって、9 の場合はoom_adj=(9 * 1000) / 17 ~= 529.411
、これらの値は整数なので、oom_score_adj
529 が保持されます。
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 になります。