C当尝试calloc最大可用内存时,没有NULL返回

时间:2016-06-05 13:29:36

标签: c malloc dynamic-memory-allocation calloc memset

我正在尝试初始化尽可能多的内存(所有可用内存),而不是睡眠10秒并将其释放。 Calloc初始化它,它有点超过7800 MB,超过我的8GB,所以我认为它完成了工作,但问题开始时(只要我正在阅读论坛和东西)OOM杀手来了并杀死它。所以进程被杀死而不是calloc返回NULL。 对此有什么解决方法吗?如何在杀死之前立即停止它或如何在内存不足时返回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;
}

1 个答案:

答案 0 :(得分:1)

通常,malloc()和朋友不会返回NULL只是因为你没有物理内存。他们通常甚至不知道你有多少物理内存,并且只是试图通过操作系统获得更多内容,通常使用mmap()(或brk(),但这只是{{1}的包装器})。

mmap()也不会因为你的物理内存不足而返回失败,但会尝试使用虚拟内存。这在UNIX系统中很常见,并且通常不可能直接使用物理内存而不是虚拟内存。 OOM杀手只是Linux的特定实现,当虚拟内存无法处理对后备存储的需求时会发生什么。让OOM杀手消失的一种方法是分配更多的交换空间(出于这个和类似的原因,我发现保持大量交换空间通常是一个好主意。)

mmap()mmap()将返回失败的最常见情况是,由于内部原因无法处理分配,例如超出虚拟地址空间(这在64位上非常罕见)系统)。

话虽如此,如果您想避免虚拟内存的潜在复杂性,存在更直接处理物理RAM的机制。一个POSIX定义的机制是malloc(),它将一定数量的已分配RAM固定到物理页面,这通常是为了避免交换的性能和/或安全隐患。它仅限于超级用户,但通常只允许锁定少量内存。有关详细信息,请参阅its manpage

在Linux上,您还可以tweak the overcommit behavior。我必须承认我自己从未尝试过,但行为#2(如链接中所述)似乎承诺某种行为类似于您似乎正在寻找的行为。

然而,这些机制都不是“普通的”,因此,如果您正在寻找一种方法来限制您的物理内存分配,这种方式可以在您个人管理的系统上轻松且可重现,那么很可能很简单。