malloc() 在 infinte 循环中

malloc() inside an infinte loop

提问人:Omkant 提问时间:12/18/2012 更新时间:12/18/2012 访问量:3539

问:

我有一个面试问题,当我们使用无限循环内部分配大块内存时会发生什么,不是吗?malloc()free()

我想过检查条件应该在堆上没有足够的内存并且它应该打破循环时工作,但它没有发生并且程序通过打印异常终止。NULLkilled

为什么会发生这种情况,为什么在没有要分配的内存时它不执行该部分(我的意思是当 malloc() 失败时)?这是什么行为?if

我的代码是:

#include<stdio.h>
#include<stdlib.h>

int main(void) {
  int *px;

  while(1)
    {
     px = malloc(sizeof(int)*1024*1024);
     if (px == NULL)
       {
        printf("Heap Full .. Cannot allocate memory \n");
        break;
       }
     else
       printf("Allocated \t");
    }
  return 0;
}

编辑:gcc - 4.5.2(Linux-Ubuntu-11.04)

C Crash Malloc Free STD

评论

0赞 ShinTakezou 12/18/2012
我认为这是一种系统保护机制,当它需要内存时,它会杀死最需要内存的进程
2赞 koopajah 12/18/2012
可能重复 stackoverflow.com/questions/2798330/...
1赞 Robert Harvey 12/18/2012
malloc 的文档说,如果函数无法分配请求的内存,它将返回 null,但它没有说明可能发生这种情况的条件。
0赞 Omkant 12/18/2012
@koopajah : 感谢您的链接. .我不可能早点找到它
0赞 Sunil Bojanapally 12/18/2012
通常,由于一个内存占用,程序在整个系统宕机之前被限制为消耗内存。

答:

1赞 matiu 12/18/2012 #1

如果您在 linux 上运行,请留意第一个终端。它将显示如下内容:

OOM error - killing proc 1100

OOM 表示内存不足。

我认为它在和/或和/或取决于 linux 发行版中也是可见的。您可以使用以下命令进行 grep:dmesg/var/log/messages/var/log/system

grep -i oom /var/log/*

你可以让你的程序慢慢地抓取内存,并注意:

watch free -m

您将看到可用的交换不断下降。当它接近于零时,Linux 会杀死你的程序,可用内存量会再次增加。

这是解释 : http://www.linuxatemyram.com/ 输出的一个很好的链接free -m


这种行为可能是启动我的 init 或其他一些保护机制(如“上帝”)的应用程序的问题,您可能会陷入 linux 杀死应用程序并 init 或其他东西再次启动它的循环。如果所需的内存量远大于可用 RAM,则可能会通过将内存页交换到磁盘而导致速度变慢。

在某些情况下,linux 不会杀死导致问题的程序,而是杀死其他一些进程。例如,如果它终止了 init,则计算机将重新启动。

在最坏的情况下,一个程序或一组进程将请求大量内存(比 Ram 中可用的内存更多)并尝试重复访问它。Linux 没有快速放置该内存的地方,因此它必须将 Ram 的某些页面交换到磁盘(交换分区)并加载从磁盘访问的页面,以便程序可以查看/编辑它。

这种情况每毫秒都会一遍又一遍地发生。由于磁盘比 RAM 慢 1000 倍,因此这个问题可能会使机器停滞不前。

评论

0赞 Omkant 12/18/2012
还有一件事..这意味着在这种情况下,malloc 不会失败,甚至不会失败一次......右?因为如果它本来有,那么它必须进入 if 大小写,因为 NULL 的返回
0赞 matiu 12/18/2012
是的,Linux Malloc 默认是懒惰/乐观的 - 它实际上不会保留内存,直到一段时间后。您可以使用以下命令将其关闭:echo 2 > /proc/sys/vm/overcommit_memory;请参阅此处的第 9.6 节: win.tue.nl/~aeb/linux/lk/lk-9.html - 也要小心该命令,我在我的机器上执行了该命令,它立即杀死了 chrome :)
1赞 tjltjl 12/18/2012 #2

行为取决于 ulimits - 参见 http://www.linuxhowtos.org/Tips%20and%20Tricks/ulimit.htm

如果你对内存使用有限制,你会看到预期的 NULL 返回行为,另一方面,如果你没有限制,你可能会看到你看到的 OOM 收割者等。

1赞 Mike 12/18/2012 #3

但它没有发生,程序通过打印杀死异常终止。

请记住,您并不孤单。在这种情况下,你被内存不足杀手杀死了,它看到你的进程占用了系统的内存,并采取了一些措施来阻止它。

为什么会发生这种情况,为什么在没有要分配的内存时它不执行 if 部分(我的意思是当 malloc() 失败时)?这是什么行为?

好吧,没有理由认为检查没有运行。查看手册页ifmalloc()

默认情况下,Linux 遵循乐观的内存分配策略。这意味着当 malloc() 返回非 NULL 时,不能保证内存确实可用。如果事实证明系统内存不足,一个或多个进程将被 OOM 杀手杀死。

因此,您认为您通过检查“保护”了自己免受内存不足的影响;实际上,这只意味着如果你拿回了 A ,你就不会推迟它,如果你真的得到了你要求的内存,这没有任何意义。NULLNULL

评论

0赞 Omkant 12/18/2012
在澄清第一个问题时......这个 OOM 内存不足是否仅在 linux 或 Windows 或其他版本的操作系统中?其他事情解释得很好..谢谢
0赞 Mike 12/18/2012
@Omkant - OOM 是一个 Linux 工具,Windows 没有这样的保护,你可以很容易地杀死 Windows。
0赞 Omkant 12/18/2012
哦,好吧,我会在 Windows 上尝试一下.还有一件事..这意味着在这种情况下,malloc 不会失败,甚至不会失败一次......右?因为如果它有,那么它一定已经进入了案例,因为 .ifNULL
0赞 Mike 12/18/2012
@Omkant - 这意味着没有返回,如果它返回,那么是的,你的代码应该已经捕获了它。malloc()NULLNULL