OOM killer

On this page 7

The OOM killer, short for out-of-memory killer, is the Linux kernel mechanism that terminates one or more processes with SIGKILL when the system or a memory-limited control group runs out of memory and nothing more can be reclaimed. Among Linux process controls, it is the last line of defense that keeps the kernel itself alive at the cost of an application.

The OOM killer exists because Linux overcommits memory by default: it lets processes reserve more virtual memory than physically exists, betting that not all of it will be used. When that bet fails, the kernel must free memory immediately, and killing a process is the only guaranteed way to do it.

How the OOM killer selects and ends a process

When an allocation fails, the kernel first tries to reclaim memory: it drops clean page cache, writes dirty pages to disk, and moves anonymous memory to swap if swap is configured. Only when reclaim makes no progress does it invoke the OOM killer.

The OOM killer then calculates a badness score for each eligible process, mainly from its resident memory, swap usage and page tables, and adjusts it with the per-process oom_score_adj value. The process with the highest score receives SIGKILL, which cannot be caught or ignored, and its memory is released.

The table below lists the interfaces that expose or influence this selection.

InterfaceRange or valuesPurpose
/proc/PID/oom_scoreRead-only numberShows the current badness score
/proc/PID/oom_score_adj-1000 to 1000Raises or lowers the chance of being killed
oom_score_adj = -1000Fixed valueExempts the process completely
OOMScoreAdjust in systemd-1000 to 1000Sets the adjustment for a service
vm.panic_on_oom0, 1 or 2Panics the kernel instead of killing a process
vm.oom_kill_allocating_task0 or 1Kills the requesting task instead of scanning
OOM killer interfaces and settings

Overcommit settings and memory limits

How often the OOM killer runs depends heavily on the overcommit policy, controlled by vm.overcommit_memory. The default heuristic mode refuses only obviously impossible allocations.

Mode valueBehaviorConsequence
0 (heuristic)Allows most allocationsDefault, OOM killer handles real shortages
1 (always)Allows every allocationUseful for some scientific workloads, higher OOM risk
2 (strict)Limits commit to swap plus a ratio of RAMAllocations fail early instead of killing later
Linux overcommit modes

In strict mode, the commit limit equals swap plus vm.overcommit_ratio percent of RAM, which defaults to 50. Applications then receive allocation errors, which only well-written software handles gracefully, so strict mode is used mainly on specialized systems.

Modern servers also run OOM handling inside control groups. When a container or systemd service reaches its cgroup v2 memory.max limit, the kernel kills a process within that cgroup only, leaving the rest of the system untouched. Setting memory.oom.group makes the kernel kill the whole group together, which avoids leaving a half-broken service running.

Several mechanisms deal with memory pressure, and they act at different stages. The OOM killer is the most drastic and the latest to act.

MechanismWhen it actsEffect
Page cache reclaimEarly, continuouslyFrees cached file data, mostly invisible
SwapUnder sustained pressureMoves idle pages to disk, slows access
systemd-oomd or earlyoomWhen pressure stays highKills in user space before the system stalls
Cgroup OOM killerWhen a group hits its limitKills inside the group only
Kernel OOM killerWhen the whole system is out of memoryKills the highest-scoring process
Memory pressure mechanisms

User-space daemons such as systemd-oomd read pressure stall information, which measures how much time tasks spend waiting for memory. They can act while the server is still responsive, whereas the kernel OOM killer often triggers only after a long period of heavy swapping in which load average climbs and the system appears frozen.

Diagnosing and preventing OOM kills

Every kernel OOM kill leaves a log entry containing the victim process, its memory usage and a table of all candidate processes. It appears in dmesg or journalctl -k with lines such as Out of memory: Killed process followed by the PID and name.

SymptomLikely causeResponse
Container exits with code 137Cgroup memory limit reachedRaise the limit or reduce application memory
Database disappears at nightBatch jobs or backups add memory loadReserve memory and protect with oom_score_adj
Repeated kills of PHP or Java workersToo many workers or heap too largeSize pools to available memory
System freezes before the killHeavy swapping without early actionEnable systemd-oomd or tune swap
Memory grows steadily over daysApplication memory leakFix the leak, restart on schedule as stopgap
OOM symptoms and responses

Prevention starts with capacity planning: the sum of maximum worker memory, database buffers and kernel needs must fit in RAM with a safety margin. Critical services can be protected with a negative adjustment, but exempting too many processes only shifts the kill to something else.

Common misconceptions

Misreading memory statistics is the most frequent source of false alarms and wrong fixes around the OOM killer.

  • Low free memory is not a problem by itself: Linux uses idle RAM for page cache, so the available column matters, not the free column.
  • Disabling the OOM killer does not add memory: a system without it hangs or panics instead.
  • Adding swap is not a cure: it delays the kill but can make the server unusably slow.
  • The victim is not always the culprit: a large but well-behaved database can be killed because a smaller process leaked memory.

Explained without jargon

Imagine a lifeboat that is about to sink because it is overloaded. Someone has to make a hard decision quickly, or everyone goes down. The OOM killer is that decision-maker inside a Linux server.

When the computer completely runs out of working memory, the system picks the program using the most memory and shuts it down immediately. This keeps the server running, but the chosen program stops without warning. The real goal is to avoid ever reaching that point by giving programs enough memory and setting sensible limits.

A typical use case

An online store runs its web application, PHP-FPM and a MySQL database on one server with 16 GB of memory. Several times a month the database stops at night, and the store shows errors until someone restarts it. The kernel log shows the OOM killer ending mysqld, the largest process.

Investigation reveals that a nightly export job and up to 80 PHP-FPM workers at about 150 MB each push memory demand past physical RAM. The administrator lowers the worker limit to 40, runs the export with a cgroup limit of 2 GB, and sets OOMScoreAdjust=-500 for the database service.

Since the change, the export occasionally fails inside its own limit, but the database has not been killed again, and the store stays online overnight.