如何强制使一个程序看起来已经耗尽了内存?

29

我有一个可能在内存耗尽时挂起的C / C ++程序。我们通过同时运行多个副本来发现这一点。我想在不完全破坏开发机器性能的情况下调试程序。是否有一种方法可以限制可用的内存,以便在请求了500K内存后,new或malloc将返回一个空指针?


Linux,具体来说是运行内核2.6.18-128.1.16.el5的32位CentOS。 - jwhitlock
当我第一次看到这个标题时,我的想法是: char *foo = new char[(1024 * 1024) * 10]; 或许是闲得无聊的怪癖吧,我可能会尝试一下,哈哈。 - Zack
然后我读了Tom在下面的答案,有点让我明白了。 - Zack
这个线程有一些额外的好主意:https://dev59.com/4HVD5IYBdhLWcg3wDG_m - jwhitlock
9个回答

31

4
这对我有用。谢谢!具体来说,我运行了程序,使用 ps 获取了进程ID,然后使用 cat /proc/PID/status 获取了VmPeak和VmSize(在我的情况下是817756kB)。然后我运行了 ulimit -v 800000 并再次尝试,很快就遇到了内存不足的情况(从malloc返回0)。我也可以在gdb下运行它(gdb --args ./program --arg1 --arg2)并跟踪代码。 - jwhitlock

9

一种方法是编写一个malloc()的包装器。

static unsigned int requested =0;

void* my_malloc(size_tamount){

   if (requested + amount < LIMIT){
       requested+=amount;
       return malloc(amount);
   }

   return NULL
}

你可以使用 #define 来重载 malloc 函数。正如 GMan 所说,你也可以为 C++ 重载 new/delete 运算符。不确定哪种方法更好,或者说这是否是你需要的。

2
更好的方法是重载全局 operator new/delete,因为所有的分配都必须通过它进行,而不需要改变任何其他代码。 - GManNickG
是的,重载new/delete会有帮助。可以将其视为malloc重载。正在编辑我的回答。 - Tom
1
你可能需要考虑在运行时通过环境变量来设置 LIMIT 的可设置性。 - William Pursell

5
  • 使用哪个操作系统?对于Unix系统,请查看您的shell(sh/csh)下的ulimit -d / limit datasize。

  • 您可以编写一个malloc的包装器,以返回您想要的情况下的错误。根据您的操作系统,您可以将其替换为实现的版本。


4
另一种方法是使用failmalloc,这是一个共享库,覆盖了malloc等函数,然后失败:-)。它可以让您控制何时失败,并可以随机失败,每n次失败等。
我自己没有使用过它,但听说效果不错。

3

重载 new 和 new[]。

void* operator new(size_t s)
{
}
void* operator new[](size_t s)
{
}

在大括号中放入您自己的代码,以选择性地在X次调用new之后结束程序。通常,您会调用malloc来分配内存并将其返回。


3
这取决于你所使用的平台。例如,在类Unix平台上,可以通过编程方式实现此目的,使用setrlimit(RLIMIT_DATA, ...)

编辑

在这种情况下,RLIMIT_AS资源也可能非常有用。


与GNU libc相比,RLIMIT_DATA是无能为力的。 - Norman Ramsey

2

我曾经有一个学生在C语言的CS 1课程中尝试过这个,但是由于内存不足而失败了:

int array[42][42][42][42][42][42][42][42][42][42][42][42][42][42][42][42][42][42][42][42][42][42][42][42][42][42][42][42][42][42][42]..... (42 dimensions);

然后他想知道为什么会出现错误...


1
难怪...他试图创建一个大小为1.5013093754529657235677197216425e+68的数组。 - RCIX

1

如果你想花钱,有一个叫做SecurityInnovations的Holodeck工具可以让你向程序中注入故障(包括低内存)。好处是你可以随意开启和关闭。我并没有真正使用过它,所以我不知道是否可以使用该工具在某些点上编程故障。我也不知道支持哪些平台...


1
据我所知,在Linux上,malloc永远不会返回空指针。相反,OOM Killer将被调用。当然,除非你已经禁用了OOM Killer。一些谷歌搜索应该能得出结果。
我知道这不是你实际的问题,但它确实与你的出发点有关。

有时候会调用OOM,有时候会得到一个空指针:http://linuxdevcenter.com/pub/a/linux/2006/11/30/linux-out-of-memory.html?page=1 - jwhitlock
2006年发表的Mulyadi Santos的文章"When Linux Runs Out of Memory"已经无法获取。以下是wayback machine的链接:https://web.archive.org/web/20160907133439/http://www.linuxdevcenter.com/pub/a/linux/2006/11/30/linux-out-of-memory.html?page=1 - jwhitlock

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接