Linux乐观的malloc:当内存不足时总是会抛出新的东西?

我一直在阅读有关Linux上的内存不足的情况,手册页中的以下段落让我想到:

默认情况下,Linux遵循乐观的内存分配策略。 这意味着当malloc()返回非NULL时,不能保证内存真的可用。 这是一个非常糟糕的错误。 如果事实certificate系统内存不足,一个或多个进程将被臭名昭着的OOM杀手杀死。 […]

考虑到操作者的新实现最终会在某个时候调用malloc,有没有什么保证新的实际上会扔在Linux上呢? 如果没有,如何处理这个明显无法察觉的错误情况?

这取决于; 您可以使用vm.overcommit_memory 配置内核的overcommit设置 。

Herb Sutter几年前曾经讨论过, 这种行为实际上是不符合C ++标准的 :

“在某些操作系统上,特别是在Linux上,内存分配总是成功的,完全停止,即使请求的内存真的不可用,分配如何始终成功?原因是分配本身只记录对内存的请求。在实际使用之前,(物理的或虚拟的)内存实际上并没有提交给请求进程,而是真正的后备存储。

“请注意,如果新的直接使用操作系统的设施,那么new将总是成功,但是任何后来的无辜的代码,比如buf [100] ='c';都会抛出或者失败或者停止。是不合格的,因为C ++标准要求,如果新的不能提交足够的内存,它必须失败(这不),而像buf [100] ='c'这样的代码不应该抛出异常或者失败威力)。”

你不能在你的软件中处理它,纯粹而简单。

对于您的应用程序,您将收到一个完全有效的指针 一旦你尝试访问它,它将在内核中产生一个页面错误,内核将尝试为它分配一个物理页面,如果它不能…繁荣。

但是,正如您所看到的,所有这些都发生在内核中,您的应用程序无法看到。 如果这是一个关键系统,则可以在系统上禁用所有的overcommit。

我认为malloc仍然可以返回NULL。 系统内存可用(RAM +交换)和进程地址空间的数量之间存在差异。

例如,如果你在一个标准的x86 linux上向malloc请求3GB的内存,它肯定会返回NULL,因为给予用户空间应用程序的内存量是不可能的。

如果我错了,请原谅我,但是不会尝试将分配的内存清零,这足以保证您获得您请求的每个字节。 或者甚至只是写入最后一个字节,如果内存不是真的那么它会抛出一个异常?

如果这是真的,你可以尝试写入内存的最后(和第一个?)字节,看看它是否正常工作,如果不是,你可以从malloc返回null。

是的,有一个保证,新的最终将抛出。 无论过度使用,地址空间的数量是有限的。 所以如果你一直在分配内存,迟早你会用尽地址空间,新的将被迫抛出。