How to handle/detect OOM Killer scenarios in a C++/GTK3 application?

Hi everyone,

I am developing a C++ application using GTK 3 and I’m trying to implement a graceful way to handle Out-of-Memory (OOM) scenarios. Specifically, I want to inform the user if the application is about to crash or has been terminated due to memory exhaustion.

The Scenario: I’ve been testing my app’s behavior by allocating 1 GB chunks using malloc. As expected, since Linux uses optimistic memory allocation, malloc returns a valid pointer (virtual memory). However, once I use memset to write to that memory, the physical RAM fills up, and the OS sends a SIGKILL to my process.

The Problem: Since SIGKILL cannot be caught or handled via signal handlers, my application dies instantly. I tried pre-creating a hidden GTKWindow to “pop up” during a failure, but because the process is killed by the kernel, I never get the chance to call gtk_widget_show().

I would appreciate any documentation or architectural advice on how to make a GTK app more resilient or “self-aware” regarding memory limits.

Just a question, but why are you concerned about Out-Of-Memory scenarios that you want to add handling for that specifically? This seems a bit odd for me.

I think it would make more sense to generally improve your application against crash scenarios, no matter the reason (power outage, system crash, user kills app manually, cat pulls out power plug…).
Because often, you will just not have the opportunity to “detect” them, just deal with them.

One way to do that would be to have an auto-save system in place, which stores important data regularly to disk. And also to use the upcoming session restore feature to maybe save specific window states, allowing it to be restored after an crash.

You can’t.

First of all, once the OS supports overcommit when allocating memory, you can’t know in advance if what you asked won’t be available.

Secondarily, while you can handle (somewhat) OOM scenarios, your entire code base, as well as every dependency, has to be written that way; a conservative estimate puts OOM handling code at a ratio of 3:1 with regular business code, which means that only very, very few OS level components are ever written to handle OOM conditions.

Which brings us to the last point: GTK uses GLib API to allocate memory. As soon as an allocation fails, GLib allocators will abort. This means you cannot really manage OOM conditions with GLib-based code.

The Linux OOM killer is well-known for being horrific. There are other mechanisms, like systemd-oomd which use cgroups and a more sensible set of resource control toggles. You’ll need a separate component that watches the org.freedesktop.oom1 interface in order to raise a notification to the user, but in practices it’s pointless to do so.

If you’re interested in watching memory pressure, you can use GMemoryMonitor inside GIO; it won’t help you with the “I allocated a ton of memory and the OOM killer descended on my process like the avenging angel of death” case, but if you change your code to smaller caches/allocations, you’ll be able to control your memory use a bit more accurately.