我一直在阅读有关Linux内存不足的情况,手册页中的以下段落让我开始思考:
默认情况下,Linux遵循乐观的内存分配策略。这意味着当malloc()返回非NULL时,不能保证内存确实可用。这是一个非常糟糕的错误。万一发现系统内存不足,一个臭名昭著的OOM杀手将杀死一个或多个进程。[…]
考虑到操作员的new实现最终会在某个时刻调用malloc,是否可以保证new实际上会在Linux上抛出?如果没有,如何处理这种显然无法检测到的错误情况?
这取决于; 您可以使用vm.overcommit_memory 配置内核的过量使用设置。
赫伯·萨特(Herb Sutter)几年前讨论了这种行为实际上是如何不符合C ++标准的:
“在某些操作系统上,尤其是Linux,内存分配总是会成功。停止。即使在请求的内存确实不可用的情况下,分配也总是能够成功吗?原因是分配本身仅记录了对内存的请求;内存分配只是记录了对内存的请求。因此,在实际使用内存之前,(物理或虚拟)内存不会真正通过实际的后备存储提交给请求过程。 “请注意,如果new直接使用操作系统的功能,那么new总是会成功,但是以后任何无辜的代码(例如buf [100] =’c’;都可能抛出,失败或停止。从标准C 的角度来看,这两种效果都一样)是不符合标准的,因为C 标准要求如果new无法提交足够的内存,它必须失败(这不会失败),并且buf [100] =’c’之类的代码不应引发异常或否则失败(这威力)。”
“在某些操作系统上,尤其是Linux,内存分配总是会成功。停止。即使在请求的内存确实不可用的情况下,分配也总是能够成功吗?原因是分配本身仅记录了对内存的请求;内存分配只是记录了对内存的请求。因此,在实际使用内存之前,(物理或虚拟)内存不会真正通过实际的后备存储提交给请求过程。
“请注意,如果new直接使用操作系统的功能,那么new总是会成功,但是以后任何无辜的代码(例如buf [100] =’c’;都可能抛出,失败或停止。从标准C 的角度来看,这两种效果都一样)是不符合标准的,因为C 标准要求如果new无法提交足够的内存,它必须失败(这不会失败),并且buf [100] =’c’之类的代码不应引发异常或否则失败(这威力)。”