什么时候应该分配到ENOMEM?

ven*_*s.w 6 c linux malloc linux-kernel

当内存用完时,内核会杀死以下程序.我想知道什么时候应该将全局变量分配给"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);
}
Run Code Online (Sandbox Code Playgroud)

R..*_*R.. 6

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

echo "2" > /proc/sys/vm/overcommit_memory
Run Code Online (Sandbox Code Playgroud)

现在malloc应该表现得很好。

  • +1,这个答案是正确的,虽然它没有解释原因:) 如果你不按照 R .. 的建议去做,给你更多关于现代 linux 系统上发生的事情的信息。分配然后只为进程保留一个虚拟地址范围,而不分配页面本身。这些只有在您第一次访问它们时才真正从内核中声明。 (2认同)
  • @MattFletcher:您可能有很多臃肿的桌面软件在运行,但已分配的内存多于可以提交的内存。:/ (2认同)

Ign*_*ams 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");
  }
}
Run Code Online (Sandbox Code Playgroud)

在您的情况下,OOM 杀手首先进入流程。

  • 你的逐渐接近极限,而我的则完全违反了极限。 (2认同)

blu*_*ift 5

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

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

为了使它表现出预期的效果,如R所说:

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