我应该在C代码中检测OOM(内存不足)错误吗?

我已经将大量的C代码用于清理标签/条件,用于失败的内存分配(由alloc系列返回NULL指示)。我被教导这是一个很好的做法,因此,在内存故障时,可以标记一个适当的错误状态,并且调用者可能会执行“优雅的内存清理”并重试。我现在对这个哲学有一些疑问,我希望清除。

我猜这可能是一个调用者可能释放过多的缓冲区空间或剥离其数据的关系对象,但是我发现这个调用者很少有能力(或者在适当的抽象级别)。此外,从被叫功能提前返回而没有副作用通常是不平凡的。

我也刚刚发现了Linux OOM杀手,这似乎使我的主要开发平台毫无意义。

By default, Linux follows an
optimistic memory allocation strategy.
This means that when malloc() returns
non-NULL there is no guarantee that
the memory really is available.
This is a really bad bug. In case it
turns out that the system is out of
memory, one or more processes will
be killed by the infamous OOM
killer.

我认为可能有其他平台遵循同样的原则。有什么务实的,使得检查OOM条件值得吗?

如果用户或系统管理员限制(见ulimit)进程的内存空间,或者操作系统支持每个用户的内存分配限制,即使在具有大量内存的现代计算机上,内存不足也可能发生。在病理病例中,分裂使得这种情况更加可能。

然而,由于在现代程序中使用动态分配的内存是很普遍的,因为很好的理由,处理内存不足错误变得非常多毛。检查和处理这种错误必须在任何地方以高昂的复杂性来完成。

我发现设计程序最好能随时崩溃。例如,确保用户创建的数据始终保存在磁盘上,即使用户没有显式保存它。 (例如,参见vi -r。)这样,您可以创建一个函数来分配内存,如果出现错误则终止程序。由于您的应用程序旨在随时处理崩溃,因此可以崩溃。用户会感到惊讶,但不会失去(很多)工作。

永不失败的分配函数可能是这样的(未经测试的,未编译的代码,仅用于演示目的):

/* Callback function so application can do some emergency saving if it wants to. */
static void (*safe_malloc_callback)(int error_number, size_t requested);

void safe_malloc_set_callback(void (*callback)(int, size_t))
{
    safe_malloc_callback = callback;
}

void *safe_malloc(size_t n)
{
    void *p;

    if (n == 0)
        n = 1; /* malloc(0) is not well defined. */
    p = malloc(n);
    if (p == NULL) {
        if (safe_malloc_callback)
            safe_malloc_callback(errno, n);
        exit(EXIT_FAILURE);
    }
    return p;
}

Valerie Aurora的文章Crash-only software可能是照亮的。

http://stackoverflow.com/questions/763159/should-i-bother-detecting-oom-out-of-memory-errors-in-my-c-code

本站文章除注明转载外,均为本站原创或编译
转载请明显位置注明出处:我应该在C代码中检测OOM(内存不足)错误吗?