什么时候应该分配到ENOMEM?

时间:2012-06-10 03:11:49

标签: c linux linux-kernel malloc

当内存用完时,内核会杀死以下程序。我想知道何时应将全局变量分配给“ENOMEM”。

#define MEGABYTE 1024*1024
#define TRUE 1
int main(int argc, char *argv[]){

    void *myblock = NULL;
    int count = 0;

    while(TRUE)
    {
            myblock = (void *) malloc(MEGABYTE);
            if (!myblock) break;
            memset(myblock,1, MEGABYTE);
            printf("Currently allocating %d MB\n",++count);
    }
    exit(0);
}

4 个答案:

答案 0 :(得分:5)

正如“R”所暗示的,问题是Linux内存管理的默认行为,即“过度使用”。这意味着内核声称可以成功地为您分配内存,但实际上在您尝试访问它之前不会分配内存。如果内核发现它分配了太多内存,它就会使用“OOM(Out Of Memory)杀手”杀死一个进程以释放一些内存。它选择杀死进程的方式很复杂,但是如果你刚刚分配了系统中的大部分内存,那么你的进程可能会成为你的进程。

如果你认为这听起来很疯狂,有些人会同意你的意见。

为了让它按照你的预期行事,正如R所说:

echo "2" > /proc/sys/vm/overcommit_memory

答案 1 :(得分:4)

首先,修复你的内核不要过度使用:

echo "2" > /proc/sys/vm/overcommit_memory

现在malloc应该正常运作。

答案 2 :(得分:4)

当您尝试一次分配太多内存时会发生这种情况。

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

int main(int argc, char *argv[])
{
  void *p;

  p = malloc(1024L * 1024 * 1024 * 1024);
  if(p == NULL)
  {
    printf("%d\n", errno);
    perror("malloc");
  }
}

在你的情况下,OOM杀手正在首先进入这个过程。

答案 3 :(得分:2)

我认为errno将设置为ENOMEM

stdio.h中定义的宏。这是documentation

#define ENOMEM          12      /* Out of Memory */

在此声明中调用malloc之后:

myblock = (void *) malloc(MEGABYTE);

函数返回NULL - 因为系统内存不足 - 。

我发现this这个问题非常有趣。

希望它有所帮助!