2

我在《理解linux内核》中读到,当malloc在用户空间被调用时,内核只是在vm_area_t结构中添加了一个线性区域,而不是在内存中分配空间,这就是所谓的ostponing分配,而这个空间是线性分配的region 只能在页面中断发生时使用。但是如果在页面中断期间不能分配页面,那么调用malloc时用户不是被骗了吗?

4

2 回答 2

0

glibc 封装的 malloc() 调用将首先从 glibc 维护的堆内存中分配。(看看malloc 期间内核中发生了什么?)如果 glibc 用完堆内存,则会调用 sys_brk 来分配更多内存。内核仅在第一次接触分配内存(主要是页面错误处理程序)时才将内存分配给用户请求。因此,我猜 calloc 将返回一个真正分配的,因为它将页面初始化为零(从手册页),它通过擦洗页面的内容来触及页面。如果在故障处理程序中无法分配新页面,这意味着系统内存非常低,要么处于大量交换中,要么将进入 OOM。

一件小事是Linux在分配给用户进程时总是清理内存,因为当页面返回给伙伴分配器时它不会这样做。

于 2012-06-02T16:43:06.343 回答
0

malloc分配的内存在写入之前不在实际内存中。另一方面,calloc分配实际内存。

从 man 手册页:

默认情况下,Linux 遵循乐观的内存分配策略。这意味着当 malloc() 返回非 NULL 时,不能保证内存确实可用。这是一个非常糟糕的错误。如果发现系统内存不足,一个或多个进程将被臭名昭著的 OOM 杀手杀死。如果在不希望突然丢失一些随机选择的进程的情况下使用 Linux,而且内核版本足够新,可以使用如下命令关闭这种过度使用行为:

   # echo 2 > /proc/sys/vm/overcommit_memory

在 glibc 的源代码中环顾四周,发现这是我认为是 calloc 的:

if (__builtin_expect (hook != NULL, 0)) {
    sz = bytes;
    mem = (*hook)(sz, RETURN_ADDRESS (0));
    if(mem == 0)
      return 0;
#ifdef HAVE_MEMCPY
    return memset(mem, 0, sz);
#else
    while(sz > 0) ((char*)mem)[--sz] = 0; /* rather inefficient */
    return mem;
#endif
  } 
于 2012-05-31T10:39:18.887 回答