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