Tune Linux OOM-Killer Preference with oom_score_adj
You will finish with a way to inspect and change one process's OOM-killer preference, verify the result, and put it back afterwards. This host has Linux man-pages 6.7-2; its installed choom reports util-linux 2.41.3. Allow about ten minutes. You need a shell and a process you own, or a clearly approved service process if you are doing operational work.
The route
Jump straight to the step you need, or tick off Done means at the end.
oom_score_adj is a preference, not a memory limit. It changes the score used when Linux must choose a process to kill because an applicable memory pool is exhausted. A positive value makes a process more likely to be selected; a negative value makes it less likely. The setting is per process and lives in /proc/<pid>/oom_score_adj.
1. Check the local interface
First confirm the files and helper available on this machine. These are ordinary, read-only commands:
$ dpkg-query -W -f='${Package} ${Version}\n' manpages
manpages 6.7-2
$ choom --version
choom from util-linux 2.41.3
The exact package revision can differ on another host. The local choom manpage was generated from util-linux 2.39.3, while the executable on this host reports 2.41.3. The kernel interface is the important part: the installed manpage documents oom_score_adj as available since Linux 2.6.36, with values from -1000 to 1000.
Checkpoint: do not confuse oom_score_adj with oom_score. The first is the adjustment you can set. The second is the current calculated score, which can change as memory use and the relevant memory context change.
2. Read a process's current values
Start with the shell running this command. Reading these files needs no elevated privileges:
$ PID=$$
$ printf 'pid=%s\n' "$PID"
pid=4105740
$ printf 'oom_score_adj='; cat "/proc/$PID/oom_score_adj"
oom_score_adj=0
$ printf 'oom_score='; cat "/proc/$PID/oom_score"
oom_score=666
The PID and score in your output will be different. A default adjustment of 0 means that no explicit preference has been added. It does not mean that the process is safe from the OOM-killer, nor that it will be selected next.
You can ask choom to read the adjustment for a PID as well:
$ choom --pid "$PID"
pid 4105740's current OOM score: 666
pid 4105740's current OOM score adjust value: 0
Treat the command name and numbers as host-specific. If the process has already exited, its /proc directory disappears and choom will fail rather than reporting a stale value.
3. Test a temporary child process
Before changing a service, use a short-lived child. This example sets an adjustment of 250 for the child only, prints both values from inside it, then exits. It does not alter the parent shell or persistent configuration:
$ choom --adjust 250 -- /bin/sh -c \
'printf "child oom_score_adj="; cat /proc/self/oom_score_adj; \
printf "child oom_score="; cat /proc/self/oom_score'
child oom_score_adj=250
child oom_score=733
The calculated score is not predictable from the adjustment alone. It also reflects estimated memory and swap use, the resources covered by the OOM event, and a small root-process weighting described by the manpage. Verify the adjustment, not an exact score.
Checkpoint: a zero exit status and the expected adjustment show that choom passed the setting to the new command. If your command is a shell wrapper, inspect the process that will actually run the workload, not only the wrapper that launches it.
4. Change a running process carefully
For a running process, save the old value, make one deliberate change, and read it back:
$ PID=$$
$ OLD_ADJ=$(cat "/proc/$PID/oom_score_adj")
$ printf 'old adjustment: %s\n' "$OLD_ADJ"
old adjustment: 0
$ choom --pid "$PID" --adjust 100
pid 4105740's OOM score adjust value changed from 0 to 100
$ cat "/proc/$PID/oom_score_adj"
100
Changing a live service is security-sensitive operational work. A large negative value can make a process a strong survivor during memory pressure, leaving less memory for other work. A large positive value can make a critical process an early candidate. Do not apply either policy to a production service without checking its owner, restart behaviour, memory limits and recovery plan.
Use elevated privileges only if the kernel rejects an otherwise authorised target. sudo does not make an incorrect PID safe. Recheck the PID immediately before writing, especially when targeting a short-lived process whose number may have been reused.
5. Restore the previous value
Restore the value you recorded when the test is over. For the shell example above, the operation is reversible:
$ choom --pid "$PID" --adjust "$OLD_ADJ"
pid 4105740's OOM score adjust value changed from 100 to 0
$ test "$(cat "/proc/$PID/oom_score_adj")" = "$OLD_ADJ"
$ echo 'adjustment restored'
adjustment restored
If the target process has exited, there is nothing left to restore. If a service manager reapplies a value after restart, inspect the unit, launch wrapper or container configuration that owns the process and change that source through your normal change process. Do not edit an unrelated file and assume it controls an existing process.
6. Handle the older oom_adj name
Older guides may mention /proc/<pid>/oom_adj. The local manpage records it as the older interface, with a range of -16 to 15 and the special value -17. It was deprecated in favour of oom_score_adj from Linux 2.6.36 and removed in Linux 3.7. Use the newer file on a current kernel.
Where a kernel still exposes both names, writing one changes the other using a scaled value. Do not mix the two scales in automation. A setting of -1000 in oom_score_adj is the special lower bound that makes the task's reported badness score zero; it is not equivalent to typing -1000 into the old interface.
Done means
- You checked the installed man-pages and util-linux versions.
- You distinguished the configurable adjustment from the changing calculated score.
- You verified a temporary child with
choombefore considering a live service. - You checked the PID immediately before changing a running process.
- You recorded and restored the previous adjustment after testing.
- You used
oom_score_adjrather than the removed legacy interface.