- 论坛徽章:
- 0
|
原帖由 Alligator27 于 2006-3-28 22:20 发表
malloc 是在用户空间, 不会管理页面. 那是kernel的事.
呵呵,是我前面没有说清楚。malloc的“页面”和我们通常意义上的页面不是一回事。前已述及,malloc和内核打交道的单位就是页面,也就是说,它与内核之间的内存交易是以页面为单位的。
为了避免经常性地调用sbrk,malloc需要自己维护它所分配的所有内存页面。如果在它自己维护的这个内存“池”里面存在能够满足要求的空闲空间,那它就没必要去调用sbrk。为了实现这个目的,malloc得先把自己名下的这些页面“组织”起来。最简单的方法就是链表,但是链表指针本身会占用页面内部的空间,这常常会造成更大的内存浪费。于是FreeBSD的malloc就把这些页面的管理信息单独找个地方来存放,也就是所谓的“页面目录”,通过这个页面目录来实现malloc页面的查找、添加、删除、合并等操作。malloc名下的每一个页面都会对应这个页面目录中的一个条目,如果因为空间原因无法生成相应的页面目录条目,对应的内存页面的分配自然也会失败。
在前面的实验中,当数据段上限增大到2934M之后,实际malloc得到的空间急速下降,1531、1195、859、523,非常整齐的等差数列。mmap的生存空间每减少1M,实际malloc的内存就减少336M,这说明,在mmap和malloc之间存在着一个非常规则的线性关系。而FreeBSD的malloc和mmap的唯一关系就是“页面目录”。我们可以看到,在上述情况下,实际malloc得到的内存离数据段的上限还差得很远,但由于mmap的生存空间已经太小,无法扩展页面目录来存放新malloc到的内存页面的管理信息,于是导致malloc失败。
原帖由 Alligator27 于 2006-3-28 22:20 发表
我试了一下, Linux/AIX的mmap是由下向上的, Solaris/HP-UX与BSDs相似, 由上向下. (BSDs我没有机器试, 以上面贴的Document说.)
不知道你实验的Linux的内核版本是多少?我之所以说Linux的mmap是从栈顶向下生长的,依据见下面的链接。看日期是2004年6月30日的邮件。从邮件内容来看,Linux的mmap原来也是从下向上生长的。我对于Linux的版本和代码不熟,目前还不能确定是否有、以及从哪一个版本开始的mmap是遵循从上到下规则的。
【Reorganizing the address space】
另外,根据我们的实验和相关文档资料,各种BSD的mmap生长方向也是不一样的。FreeBSD从下到上,NetBSD从上到下。可参考我前面画出的FreeBSD和Linux进程地址空间的布局示意图。
[ 本帖最后由 雨丝风片 于 2006-3-29 08:19 编辑 ] |
|