Ich versuche, den Wert für den „Out of Memory Killer“ festzulegen oom_adj
und jedes Mal, wenn ich das tue (unabhängig vom Prozess), erhalte ich genau eins weniger als von mir festgelegt (zumindest für positive Ganzzahlen. Negative Ganzzahlen habe ich nicht ausprobiert, da ich möchte, dass diese Prozesse zuerst vom „OOM Killer“ beendet werden).
[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 ~]#
Ist das zu erwartendes Verhalten? Wenn nicht, warum passiert das?
Antwort1
oom_adj
ist veraltet und wird nur für Legacy-Zwecke bereitgestellt. Intern verwendet Linux, oom_score_adj
was einen größeren Bereich hat: oom_adj
geht bis 15, während oom_score_adj
geht bis 1000.
oom_adj
Immer wenn Sie (sagen wir mal 9) schreiben, macht der Kernel Folgendes:
oom_adj = (oom_adj * OOM_SCORE_ADJ_MAX) / -OOM_DISABLE;
und speichert das in oom_score_adj
. OOM_SCORE_ADJ_MAX
ist 1000 und OOM_DISABLE
ist -17.
Für 9 erhalten Sie also oom_adj=(9 * 1000) / 17 ~= 529.411
und da es sich bei diesen Werten um Ganzzahlen handelt, oom_score_adj
ergibt sich 529.
Wenn Sie jetzt lesen, oom_adj
wird der Kernel Folgendes tun:
oom_adj = (task->signal->oom_score_adj * -OOM_DISABLE) / OOM_SCORE_ADJ_MAX;
Für 529 erhalten Sie also: oom_adj = (529 * 17) / 1000 = 8.993
und da der Kernel ganze Zahlen und Ganzzahlarithmetik verwendet, wird daraus 8.
Sie schreiben also 9 und erhalten 8 aufgrund der Festkomma-/Ganzzahlarithmetik.