2021-03-05 23:46:08 +02:00
2021-03-03 21:10:18 +02:00
2021-03-03 21:10:55 +02:00
2021-03-03 21:11:10 +02:00
2021-03-03 21:11:30 +02:00
2021-03-05 23:46:08 +02:00

earlyoom - The Early OOM Daemon

The oom-killer generally has a bad reputation among Linux users. This may be part of the reason Linux invokes it only when it has absolutely no other choice. It will swap out the desktop environment, drop the whole page cache and empty every buffer before it will ultimately kill a process. At least that's what I think that it will do. I have yet to be patient enough to wait for it, sitting in front of an unresponsive system.

This made me and other people wonder if the oom-killer could be configured to step in earlier: [reddit r/linux][5], [superuser.com][2], [unix.stackexchange.com][3].

As it turns out, no, it can't. At least using the in-kernel oom-killer. In the user space, however, we can do whatever we want.

What does it do

earlyoom checks the amount of available memory and free swap up to 10 times a second (less often if there is a lot of free memory). By default if both are below 10%, it will kill the largest process (highest oom_score). The percentage value is configurable via command line arguments.

In the free -m output below, the available memory is 2170 MiB and the free swap is 231 MiB.

              total        used        free      shared  buff/cache   available
Mem:           7842        4523         137         841        3182        2170
Swap:          1023         792         231

Why is "available" memory checked as opposed to "free" memory? On a healthy Linux system, "free" memory is supposed to be close to zero, because Linux uses all available physical memory to cache disk access. These caches can be dropped any time the memory is needed for something else.

The "available" memory accounts for that. It sums up all memory that is unused or can be freed immediately.

Note that you need a recent version of free and Linux kernel 3.14+ to see the "available" column. If you have a recent kernel, but an old version of free, you can get the value from grep MemAvailable /proc/meminfo.

When both your available memory and free swap drop below 10% of the total, it will send the SIGTERM signal to the process that uses the most memory in the opinion of the kernel (/proc/*/oom_score). It can optionally (-i option) ignore any positive adjustments set in /proc/*/oom_score_adj to protect innocent victims (see below).

See also

  • nohang, a similar project like earlyoom, written in Python and with additional features and configuration options.
  • facebooks's pressure stall information (psi) kernel patches and the accompanying oomd userspace helper. The patches are merged in Linux 4.20.

Why not trigger the kernel oom killer?

Earlyoom does not use echo f > /proc/sysrq-trigger because the Chrome people made their browser (and all electron-based apps - vscode, skype, discord etc) always be the first (innocent!) victim by setting oom_score_adj very high. Instead, earlyoom finds out itself by reading through /proc/*/status (actually /proc/*/statm, which contains the same information but is easier to parse programmatically).

Additionally, in recent kernels (tested on 4.0.5), triggering the kernel oom killer manually may not work at all. That is, it may only free some graphics memory (that will be allocated immediately again) and not actually kill any process. Here you can see how this looks like on my machine (Intel integrated graphics).

How much memory does earlyoom use?

About 2 MiB (VmRSS), though only 220 kiB is private memory (RssAnon). The rest is the libc library (RssFile) that is shared with other processes. All memory is locked using mlockall() to make sure earlyoom does not slow down in low memory situations.

Use

Just start the executable you have just compiled:

./earlyoom

It will inform you how much memory and swap you have, what the minimum is, how much memory is available and how much swap is free.

./earlyoom
earlyoom v1.4-6-ga4021ae
mem total: 9823 MiB, swap total: 9823 MiB
sending SIGTERM when mem <= 10 % and swap <= 10 %,
        SIGKILL when mem <=  5 % and swap <=  5 %
Could not lock memory - continuing anyway: Cannot allocate memory
mem avail:  5091 of  9823 MiB (51 %), swap free: 9823 of 9823 MiB (100 %)
mem avail:  5084 of  9823 MiB (51 %), swap free: 9823 of 9823 MiB (100 %)
mem avail:  5086 of  9823 MiB (51 %), swap free: 9823 of 9823 MiB (100 %)

[...]
Description
earlyoom for Artix Linux
Readme 37 KiB
Languages
Shell 100%