Я пытаюсь установить 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 из-за арифметики с фиксированной точкой/целыми числами.