Значение OOM Killer всегда на единицу меньше установленного

Значение OOM Killer всегда на единицу меньше установленного

Я пытаюсь установить oom_adjзначение для функции-убийцы нехватки памяти, и каждый раз, когда я это делаю (независимо от процесса), я получаю ровно на единицу меньше, чем установил (по крайней мере, для положительных целых чисел. Я не пробовал отрицательные целые числа, так как хочу, чтобы эти процессы сначала были завершены функцией-убийцей 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 из-за арифметики с фиксированной точкой/целыми числами.

Связанный контент