2014-05-15 34 views
0

我想通过以下功能捕捉内存溢出异常:如何抓住内存溢出异常在Ubuntu

void allocMemory(buffer& thebuf, size_t size) 
{ 
try 
{ 
     thebuf = buffer(size); // new char[] here 
} 
catch(bad_alloc& ex) 
{ 
    exception handling... // print some information 
     exit(1); 
} 
} 

的处理应该显示一些信息和关闭程序。这项工作在Windows上很好,但在Linux上,程序直接与终端上的“Killed”关闭。看起来OOM杀手在异常可以捕捉之前杀死我的程序。

这是正常的吗?

如何捕获Linux上的内存异常?

P.S.我正在测试Ubuntu 12.04 64位,仅使用4GB内存进行测试,没有交换空间,语言是C++。另外,如果我一次新增大量内存,该功能在Linux上也可以使用。但是,如果我每次新增一点点(例如:在一个循环中),程序将最终以终止的“Killed”关闭。

任何帮助,将不胜感激。

回答

0

你想是这样的:

try { 
    thebuf = new buffer[size]; 
} catch(std::bad_alloc& ex) { 
    std::cout << ex.what(); 
    exit(1); 
} 
1

您可以配置Linux不过量使用内存。

Overcommitting通常是件好事。飞机票也超卖,这偶尔会导致飞机超额预订,他们可能需要改变某人的航班。但通常情况并非如此。这同样适用于从Linux请求内存的应用程序。就像我所说的,你可以配置Linux不要过度使用内存。请参阅this question

+0

感谢您的链接。但是由于我们的用户可能没有root权限,因此可能无法要求他们配置Linux,是否有更好的方法来检测Linux上的内存不足? –

4

在Linux上,您不会得到任何bad_alloc异常(除非您更改了shell中的某些默认值)。

Linux使用懒惰分配策略。任何分配请求(当不太大时)都会成功。操作系统将返回一个未映射到虚拟内存的地址。映射发生在程序实际尝试使用内存时。只有在此时才能检测到内存不足的情况。

但是,发生这种情况时,向计划报告情况已为时过晚。它不准备处理它。所以操作系统只是彻底杀死了这个程序。

谷歌linux内存不足杀手 for(lots)更多信息。

您可以用rlimit命令限制程序可用的内存量。将其设置得足够低,以便程序在耗尽所有可用内存之前达到极限。

如果需要,您也可以禁用系统惰性分配行为,但这很少是件好事。

+0

解释非常清楚,所以在Linux上看起来不可能发现OOM错误。我想做的是在OOM发生时给用户一个反馈,并顺利关闭该程序,是否有一种在Linux上完成的好方法? –

+0

该进程因无法捕获的信号而中止,因此您可以做的最好的做法是启动另一个可充当监督者的小型进程。 –