关于c ++:Linux乐观的malloc:内存不足时,新的将总是抛出吗?

Linux optimistic malloc: will new always throw when out of memory?

我一直在阅读有关Linux内存不足的情况,手册页中的以下段落让我开始思考:

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. [...]

考虑到操作员的new实现最终会在某个时刻调用malloc,是否有任何保证new会真正在Linux上抛出? 如果没有,如何处理这种显然无法检测到的错误情况?


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

赫伯·萨特(Herb Sutter)几年前讨论了这种行为实际上是如何不符合C ++标准的:

"On some operating systems, including specifically Linux, memory allocation always succeeds. Full stop. How can allocation always succeed, even when the requested memory really isn't available? The reason is that the allocation itself merely records a request for the memory; under the covers, the (physical or virtual) memory is not actually committed to the requesting process, with real backing store, until the memory is actually used.

"Note that, if new uses the operating system's facilities directly, then new will always succeed but any later innocent code like buf[100] = 'c'; can throw or fail or halt. From a Standard C++ point of view, both effects are nonconforming, because the C++ standard requires that if new can't commit enough memory it must fail (this doesn't), and that code like buf[100] = 'c' shouldn't throw an exception or otherwise fail (this might)."


您不能在您的软件中处理它,既简单又简单。

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

但是正如您所看到的,所有这些都发生在内核内部,您的应用程序看不到它。如果它是关键系统,则可以在系统上一起禁用所有过量使用。


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

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


如果我错了,请原谅我,但不会尝试将分配的内存清零以足以确保您拥有所请求的每个字节吗?甚至只是写入最后一个字节,如果内存不是您真正的权利,它也会引发异常?

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


是的,有保证,新产品最终会投入市场。不管过量使用,地址空间的数量都是有限的。因此,如果您继续分配内存,迟早您将用完地址空间,而新的将被强制抛出。