我在Bruce Eckel的《Thinking in C++,第2版,卷1》第13章中找到了这个有趣的练习:
/*13. Modify NoMemory.cpp so that it contains an array of int
and so that it actually allocates memory instead of
throwing bad_alloc. In main( ), set up a while loop like
the one in NewHandler.cpp to run out of memory and
see what happens if your operator new does not test to
see if the memory is successfully allocated. Then add the
check to your operator new and throw bad_alloc*/
#include <iostream>
#include <cstdlib>
#include <new> // bad_alloc definition
using namespace std;
int count = 0;
class NoMemory {
int array[100000];
public:
void* operator new(size_t sz) throw(bad_alloc)
{
void* p = ::new char[sz];
if(!p)
{
throw bad_alloc(); // "Out of memory"
}
return p;
}
};
int main() {
try {
while(1) {
count++;
new NoMemory();
}
}
catch(bad_alloc)
{
cout << "memory exhausted after " << count << " allocations!" << endl;
cout << "Out of memory exception" << endl;
exit(1);
}
}
我的问题是:为什么这段代码在完全耗尽内存时(根据Win7的资源监视器),不会抛出bad_alloc异常呢?我假设全局的::new char[sz]从未返回0,即使内存已满。但是为什么呢?甚至一旦内存用尽,它将使Win7操作系统变得麻痹、无响应,但它仍然继续尝试分配新空间。
(有一个有趣的补充:我也在Ubuntu上尝试了它:也没有抛出bad_alloc异常,但这个危险的进程在被操作系统杀死之前,不进行冻结处理——很聪明,不是吗?)
new (noexcept version)
还是malloc
,都会出现相同的行为,因为操作系统总是会处理它们。您可以尝试通过ulimit
限制应用程序的内存访问,并且我相信这将允许您的应用程序达到预期的效果。否则,请阅读OOM Killer
策略。 - Victor Polevoy