Linux Malloc 的意外行为


#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);
}

当块大小为 1024*1024 时。 一切都很好。 Malloc 返回 NULL,循环中断。程序打印文本并退出。
当块大小为 4096 时Malloc 从不返回空程序崩溃。=>内存不足,被内核杀死。为什么?

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

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

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

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

如果需要,可以将 OOM killer 配置为让您独自一人,方法是将调整值 -17 写入 procfs 中的oom_adj条目。除非您知道自己在做什么,否则这是不可取的,因为它会使其他(也许更重要的(流程面临风险。从-16+15的其他值调整选择过程的可能性。

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

相关内容

  • 没有找到相关文章

最新更新