Linux乐观的malloc:当内存不足时,新的总会抛出吗?

rpg*_*rpg 22 c++ linux memory-management out-of-memory

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

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

考虑到运营商的新实现最终会在某个时刻调用malloc,是否有任何保证新的实际上会抛出Linux?如果没有,那么如何处理这个明显无法察觉的错误情况呢?

Jam*_*lis 18

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

Herb Sutter几年前曾讨论过这种行为实际上与C++标准不一致:

"在某些操作系统上,包括特别是Linux,内存分配总是成功.完全停止.即使请求的内存真的不可用,分配如何总是成功?原因是分配本身只记录了对内存的请求;在封面下,(物理或虚拟)内存实际上并未提交给具有真实后备存储的请求进程,直到实际使用内存为止.

"请注意,如果new直接使用操作系统的设施,那么new将永远成功,但任何后来的无辜代码,如buf [100] ='c';可以抛出或失败或停止.从标准C++的角度来看,两种效果是不符合的,因为C++标准要求如果new不能提交足够的内存,它必须失败(这不会),并且像buf [100] ='c'这样的代码不应抛出异常或以其他方式失败(这威力)."

  • `buf [100] ='c'`不会失败或抛出异常.该应用程序可能会在该时间内被系统杀死,但应用程序可能会在*any*时被系统杀死. (13认同)

246*_*tNt 9

您无法在软件中处理它,纯粹而简单.

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

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