【问题标题】:C When trying to calloc maximum free memory, no NULL returnC 尝试调用最大空闲内存时,不返回 NULL
【发布时间】:2016-10-05 04:17:46
【问题描述】:

我正在尝试初始化尽可能多的内存(所有可用内存),而不是休眠 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;
}

【问题讨论】:

  • 1000000000000 不适合 int 如果它是 32 位长。
  • 我只是编辑了代码并改用了while。谢谢,结果还是一样
  • 将错误类型的数据传递给printf() 将调用未定义的行为。转换为所需的类型将使其安全。
  • 这都是依赖于系统的东西...... OOM 杀手并不是一个 posix 结构......
  • 你正在使用calloc()来初始化内存。所以我删除了我的评论。对不起。无论如何,您可能想让自己对“Overcommitting”的概念感到满意。

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


【解决方案1】:

一般情况下,malloc() 和朋友不会仅仅因为您的物理 RAM 不足而返回 NULL。他们通常甚至不知道你有多少物理内存,只会尝试从操作系统中获取更多内存,通常使用mmap()(或brk(),但这只是mmap() 的包装)。

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

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

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

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

但是,这些机制都不是“普通”的,因此,如果您正在寻找一种方法来限制对物理内存的分配,这种方式在您不亲自管理的系统上可移植且可重现,那么您很可能是运气不好,很简单。

【讨论】:

  • mmap 将文件映射到内存。 malloc & co. 肯定不会使用它。
  • @Olaf:也用于映射匿名内存。见MMAP_ANONYMOUS。
  • malloc 在下面使用 sbrk 和 brk(参见 K&R 的第 8 章)
  • @stackptr: 当然可以,但是在 Linux 上brk() 只是mmap() 的包装,因此查看后者的一般行为更有用。此外,malloc() 将在数据段用完时开始使用mmap(),这在地址空间中大量映射段的 32 位架构上尤其常见。
  • @Dolda2000 sbrk 不只是将指针推进到堆的末尾吗?
猜你喜欢
  • 2015-04-29
  • 1970-01-01
  • 1970-01-01
  • 2012-12-06
  • 1970-01-01
  • 2015-05-19
  • 2012-09-18
  • 2017-05-07
  • 2011-09-05
相关资源
最近更新 更多