Estoy tratando de establecer el oom_adj
valor para el asesino de falta de memoria, y cada vez que lo hago (independientemente del proceso) obtengo exactamente uno menos de lo que configuré (al menos para números enteros positivos. No he probado números enteros negativos desde que desea que OOM Killer elimine estos procesos primero).
[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 ~]#
¿Es este el comportamiento esperado? Si no, ¿por qué sucede esto?
Respuesta1
oom_adj
está en desuso y se proporciona únicamente para fines heredados. Internamente usa Linux oom_score_adj
el que tiene mayor rango: oom_adj
sube hasta 15 mientras que oom_score_adj
sube hasta 1000.
Cada vez que escribes en oom_adj
(digamos 9), el kernel hace esto:
oom_adj = (oom_adj * OOM_SCORE_ADJ_MAX) / -OOM_DISABLE;
y lo almacena en oom_score_adj
. OOM_SCORE_ADJ_MAX
es 1000 y OOM_DISABLE
es -17.
Entonces, para 9 obtendrás oom_adj=(9 * 1000) / 17 ~= 529.411
y, dado que estos valores son números enteros, oom_score_adj
contendrá 529.
Ahora cuando leas oom_adj
el kernel hará esto:
oom_adj = (task->signal->oom_score_adj * -OOM_DISABLE) / OOM_SCORE_ADJ_MAX;
Entonces, para 529 obtendrás: oom_adj = (529 * 17) / 1000 = 8.993
y dado que el núcleo usa números enteros y aritmética de enteros, esto se convertirá en 8.
Entonces... escribes 9 y obtienes 8 debido a la aritmética de punto fijo/enteros.