1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include<pthread.h>

#define BLOCKSIZE 1024*1024
// #define BLOCKSIZE 4096
int main (int argc, char *argv[])
{
    void *myblock = NULL;
    int count = 0;
    while (1)
    {
        myblock =  malloc(BLOCKSIZE);
        if (!myblock){
            puts("error"); break;
        }
        memset(myblock,1, BLOCKSIZE);
        count++;
    }
    printf("Currently allocated %d \n",count);
    printf("end");
    exit(0);
}

当 BLOCKSIZE 为 1024*1024 时。一切正常。malloc 返回 NULL,循环中断。程序打印文本并退出。
当 BLOCKSIZE 为 4096 时,Malloc 永远不会返回 NULL 程序崩溃。=> 内存不足,被内核杀死。为什么?

4

1 回答 1

2

一片漆黑,你很可能会被OOM杀手吃掉。

Linux 有一个叫做OOM 杀手的东西,当它发现内存分配非常繁重时,它会四处寻找终止进程。选择要杀死的进程是基于每个进程的某些属性(例如分配大量内存的主要候选者)。

它这样做,部分原因在于其乐观的内存分配策略(无论设备上是否有足够的后备内存,它通常都会为您提供地址空间,这就是所谓的过度使用)。

在这种情况下,当一次分配 1M 时,可能会在 OOM 杀手找到您之前分配失败。使用 4K,您在分配例程决定您已经受够之前就被发现了。

如果这是您的愿望,您可以配置 OOM 杀手让您一个人呆着,方法是将调整-17oom_adj写入procfs. 除非您知道自己在做什么,否则这是不可取的,因为它会使其他(也许更重要的)流程处于危险之中。其他值-16用于+15调整您的流程被选中的可能性。

vm.overcommit_memory=2您也可以通过写入来完全关闭过度使用,/etc/sysctl.conf但这又会在您的环境中出现问题。

于 2013-08-12T01:12:53.877 回答