【问题标题】:unexpected behavior of linux malloclinux malloc 的意外行为
【发布时间】:2013-08-12 01:01:13
【问题描述】:
#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 程序崩溃。 => 内存不足,被内核杀死。 为什么?

【问题讨论】:

  • malloc 仅在无法分配内存时返回 NULL。当你降低块大小时,你可以分配所有的块,因为你从来没有释放它们,你会得到一个 OOM 错误。

标签: linux null malloc


【解决方案1】:

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

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

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

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

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

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

【讨论】:

  • 程序员:分配内存。 Linux:什么,徒手?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-03-23
  • 1970-01-01
  • 2021-03-13
  • 1970-01-01
  • 2012-05-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多