用户态进程是否可以处理 linux 中的 OOM 错误?

Is it possible for a userland process to handle OOM error in linux?

假设我禁用了所有 oom 相关功能(没有 OOM 杀手)。一个进程已经占用了所有可用内存,并且它仍在尝试从映射磁盘文件中读取一些字节,该文件不在任何页面缓存中。此进程是否会收到 OOM 信号,以便它可以反应性地释放一些内存并稍后重试?

如果您禁用了 oom-killer,那么进程将不会收到信号,但是一旦内存耗尽,malloc() 调用就会失败。

这取决于很多条件。

1)如何禁用 oom-killer?

假设您将 2 写入 /proc/sys/vm/overcommit_memory, 这意味着:

2:始终检查,永不过度使用(参见 man 5 proc)

之后你调用了 mmap。

2)你在"mmap"中使用什么标志?

假设您使用 MAP_NORESERVE, 在另一种情况下(没有 MAP_NORESERVE) mmap 只是 return 错误, 如果物理内存不够。

3)你的overcommit_ratio值是多少? 假设它不为零,如果为零则 mmap return 错误, 我们不能处于 "no pages for file".

的情况

如果所有这些假设都是正确的,那么您会得出: mm/oom_kill.c::pagefault_out_of_memory,

又是新情况:

4)可能我们在禁用oom的cgroup中?

如果是,那我们就去睡觉吧。

最后调用 oom-killer

关于禁用oom

And by "we just go to sleep", do you mean a system pause?

参见 linux-source/Documentation/cgroups/memory.txt:

如果 OOM-killer 被禁用,cgroup 下的任务将 hang/sleep 在内存 cgroup 的 OOM 等待队列中,当他们请求负责的内存时。

因此,禁用 oom-killer 的那部分 cgroup 进入休眠状态, 并非所有系统。

Is it possible that we, the userland process handle this pagefault?

1)可以这样做: https://lwn.net/Articles/550555/

2)或者您可以只观看 oom-killer 事件。

再看linux-source/Documentation/cgroups/memory.txt:

memory.oom_control文件用于OOM通知和其他控制。

内存cgroup使用cgroup通知实现OOM通知 API(参见 cgroups.txt)。它允许注册多个 OOM 通知 交付并在发生 OOM 时收到通知。

要注册通知程序,应用程序必须:...