10

以下程序在内存耗尽时被内核杀死。我想知道何时应将全局变量分配给“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

4 回答 4

6

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

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

现在malloc应该行为正常。

于 2012-06-10T03:16:55.597 回答
5

正如“R”所暗示的,问题在于 Linux 内存管理的默认行为,即“过度使用”。这意味着内核声称已成功分配内存,但直到稍后您尝试访问它时才真正分配内存。如果内核发现它分配了太多内存,它会使用“OOM(Out Of Memory)杀手”杀死一个进程以释放一些内存。它选择要杀死的进程的方式很复杂,但是如果您刚刚分配了系统中的大部分内存,那么可能会是您的进程获得子弹。

如果您认为这听起来很疯狂,那么有些人会同意您的看法。

为了让它像你期望的那样运行,正如 R 所说:

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

于 2012-06-10T05:46:16.277 回答
5

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

#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 杀手首先进入流程。

于 2012-06-10T03:17:39.403 回答
3

我认为errno将设置为ENOMEM

中定义的宏stdio.h。这是文档

#define ENOMEM          12      /* Out of Memory */

在此语句中调用 malloc 后:

myblock = (void *) malloc(MEGABYTE);

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

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

希望能帮助到你!

于 2012-06-10T03:19:13.307 回答