The files /proc/<pid>/oom_adj
and /proc/<pid>/oom_score_adj
adjust the same setting in the kernel and you can modify either one. The difference is that the older interface oom_adj
uses more coarse scale from -16
to 15
whereas newer oom_score_adj
uses scale from -1000
to 1000
.
You can verify that both files control the same setting like this (in shell):
$ cd /proc/$$
$ grep . oom_*
oom_adj:0
oom_score:0
oom_score_adj:0
$ echo 500 > oom_score_adj
$ grep . oom_*
oom_adj:8
oom_score:500
oom_score_adj:500
$ echo 10 > oom_adj
$ grep . oom_*
oom_adj:9
oom_score:588
oom_score_adj:588
I used Linux kernel version 5.4.119 which seems to have off-by-one behavior for the older interface. I'm not sure if this intentional or not. The read-only file oom_score
returns the actually used value which should be identical to oom_score_adj
.
Setting negative values for either file requires root access so this can be used only to volunteer to be killed in case of system running out of memory (OOM).
The way oom_score
works is checking the actual memory usage of a process and then counting 1000 * memory_usage_of_process / total_usable_memory_in_system + oom_score
to get a comparision number for every process. The higher the number you get, the more probable its for OOM Killer to select the given process (in addition to memory usage, the amount of child processes are considered, too). The value of -1000
for oom_score
is special because it cannot be selected by OOM Killer no matter the computed value of the above computation. In most cases the resulting value would be negative enough to not be selected in any case.
And you can use either of these to volunteer your shell (script or not) as the volunteer for killing in case system runs out of memory. Note that all new processes launched by a process will inherit the same oom_score_adj
value by default so you can basically write a shell script that does
#!/bin/bash
echo 1000 > /proc/$$/oom_score_adj
the-command-that-should-be-killed-if-oom
echo 0 > /proc/$$/oom_score_adj
That way only the-command-that-should-be-killed-if-oom
(and it's subprocesses) will end up with oom_score_adj
value 1000 and your script is still using the value 0 after the third line. You can obviously skip the last line if the script doesn't need to do anything after the process exits – in that case you should also use exec
to save some RAM by not keeping the shell script alive after starting the process.
echo <new-oom-adj-value > /proc/<pid>/oom_score_adj
method but looking for an API to call.