繁体   English   中英

在无限循环内的malloc()

[英]malloc() inside an infinte loop

我遇到一个访谈问题,当我们在无限循环内使用malloc()分配大量内存而不free()它时,会发生什么情况。

我想检查与条件的NULL当没有对堆没有足够的内存,它应该打破循环应该工作,但它并没有发生,程序通过打印异常终止killed

为什么会发生这种情况,为什么在没有内存分配时(我的意思是当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)

如果您在Linux上运行,请关注第一个终端。 它将显示如下内容:

OOM error - killing proc 1100

OOM意味着内存不足。

我认为它也可以在dmesg和/或/var/log/messages和/或/var/log/system中看到,具体取决于Linux发行版。 您可以使用以下命令进行grep:

grep -i oom /var/log/*

您可以使程序缓慢地获取内存,并注意:

watch free -m

您将看到可用交换掉下来。 当它几乎消失时,Linux将杀死您的程序,并且可用内存量将再次增加。

这是解释free -m输出的重要链接: http : //www.linuxatemyram.com/


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

在某些情况下,Linux不会杀死引起麻烦的程序,但会杀死其他进程。 例如,如果它杀死了init,则计算机将重新启动。

在最坏的情况下,一个程序或一组进程会请求大量内存(超过Ram中可用的内存),然后尝试重复访问它。 Linux没有足够快的空间来放置该内存,因此它必须将Ram的某些页面换出到磁盘(交换分区)并加载要从磁盘访问的页面,以便程序可以查看/编辑它。

这每隔一毫秒就会发生一次又一次。 由于磁盘的速度比RAM慢1000倍,因此此问题会使计算机陷入停顿。

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

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

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

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

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

好吧,没有理由相信if检查没有运行。 查看手册页中的malloc()

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

因此,您认为您使用NULL检查“保护”自己免受内存不足的情况的影响; 实际上,这仅意味着如果您返回NULL ,就不会引用它,这与您是否真正获得了所请求的内存无关。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM