C 尝试调用最大可用内存时,没有 NULL return

C When trying to calloc maximum free memory, no NULL return

我正在尝试初始化尽可能多的内存(所有空闲内存),而不是休眠 10 秒并释放它。 Calloc 初始化它,它超过 7800 MB,超出我的 8GB,所以我认为它完成了工作,但问题开始于(只要我正在阅读论坛和东西)OOM 杀手来杀它。所以进程被杀死而不是 calloc returning NULL。 有什么解决办法吗?如何在杀死之前立即停止它或如何在内存不足时 return NULL?

int main() {

int *pointer;
int megabajti=1048576; //MB
int velikost_strani=4096; //page size
long long int i=0;
while(1)
{
    pointer=calloc(velikost_strani,sizeof(int));
    printf("Trenutno alociram %lld MB\n",i*velikost_strani*sizeof(int)/megabajti);
    if(pointer==NULL)
    {
        printf("Max velikost je %lld MB\n",i*velikost_strani*sizeof(int)/megabajti);
        free(pointer);
        sleep(10);
    }
++i;
}
return 0;
}

一般来说,malloc()朋友们不会returnNULL只是因为你的物理内存不足。他们通常甚至不知道你有多少物理 RAM,只会尝试从 OS 中获取更多内存,通常使用 mmap()(或 brk(),但这只是mmap()).

mmap() 也不会 return 仅仅因为物理 RAM 不足而失败,而是会尝试使用虚拟内存。这在 UNIX 系统中很常见,并且 通常 不可能直接使用物理内存而不是虚拟内存。 OOM-killer 只是 Linux' 虚拟内存无法处理后备存储需求时所发生情况的具体实现。消除 OOM 杀手的一种方法是分配更多交换空间 space(出于这个原因和类似的原因,我发现保留大量交换空间 space 通常是个好主意)。

mmap()malloc() 将 return 失败的最常见情况是它们由于内部原因无法处理分配,例如超出虚拟地址 space(这在 64 位系统上很少见)。

也就是说,如果您想避免虚拟内存的潜在复杂性,则存在更直接地处理物理 RAM 的机制。 POSIX 定义的一种机制是 mlock(),它将一定数量的已分配 RAM 固定到物理页面,通常这样做是为了避免性能 and/or 交换带来的安全隐患。但是,它仅限于超级用户,并且通常只允许总共锁定少量内存。有关详细信息,请参阅 its manpage

在 Linux 上,您还可以 tweak the overcommit behavior。我不得不承认我自己从未尝试过,但是行为 #2(如 link 中所述)似乎预示着某种类似于您正在寻找的行为。

然而,

None 这些机制是 "ordinary",因此如果您正在寻找一种方法来限制对物理内存的分配,以便在您的系统上可移植且可重现不要亲自管理,你可能运气不好,很简单。