分享
 
 
 

Apache内存池内幕(6)

王朝system·作者佚名  2006-01-27
窄屏简体版  字體: |||超大  

2.4.4内存池的内存分配

从内存池中分配内存通过两个函数实现:apr_pcalloc和apr_palloc,这两个函数唯一的区别就是apr_pcalloc分配后的内存全部自动清零,而apr_palloc则省去了这一步的工作。

apr_palloc的函数原型如下所示:

APR_DECLARE (void *) apr_palloc (apr_pool_t *pool, apr_size_t size)

函数中pool是需要分配内存的内存池,size则是需要分配的内存的大小。一旦分配成功则返回分配内存的地址。

在了解内存池的内存分配之前,我们应该对active链表有所了解。顾名思义,active链表中保存的都是曾经被使用或者正在被使用的apr_memnode_t内存结点。这些结点都是由分配子进行分配,之所以被使用,一个重要的原因就是它们有足够空闲的空间。将这些结点保存在active上,这样下次需要内存的时候只要首先遍历active链表即可,只有在active链表中的结点不能够满足分配要求的时候才会重新跟分配子申请新的内存。另一方面,一旦某个结点被选中进入active链表,那么它就不能在原先的分配子链表中存在。

对于每一个apr_memnode_t内存结点,它的实际可用空间为endp-first_avail的大小。但是正如前面所说,Apache中衡量空间通常使用索引的方法,对于所有的结点,它的空闲空间用free_index描述。为了加快查找速度,active链表中的所有的结点按照其空间空间的大小进行反向排序,为此空闲空间大得总是排在前面,空闲空间最小的则肯定排在最末尾。对于指定的分配空间,只要将其与第一个结点的空闲空间进行比较,如果第一个空闲都不满足,那么此时必须向分配子重新申请空间,否则直接从第一个结点中分配空间,同时调整分配后的结点次序。

apr_memnode_t *active, *node;

void *mem;

apr_size_t free_index;

size = APR_ALIGN_DEFAULT(size);

active = pool->active;

if (size < (apr_size_t)(active->endp - active->first_avail)) {

mem = active->first_avail;

active->first_avail += size;

return mem;

}

分配首先计算需要分配的实际空间,这些空间都是使用对齐算法调整过的。Apache首先尝试到active链表的第一个结点中去分配空间,正如前面所言,这个是链表中空闲最多的结点,如果它能够满足需要,Apache直接返回size大小的空间,同时调整新的first_avail指针。不过这里需要注意的是对于空链表的情况。当一个内存池使用apr_create_pool_ex新创建以后,它的active链表为空,不过此时active并不为NULL,事实上active=node,意味着active指向内存池所在的内存结点。因此这种情况下,空间的分配并不会失败。

node = active->next;

if (size < (apr_size_t)(node->endp - node->first_avail)) {

list_remove(node);

}

else {

if ((node = allocator_alloc(pool->allocator, size)) == NULL) {

if (pool->abort_fn)

pool->abort_fn(APR_ENOMEM);

return NULL;

}

}

如果active链表中的结点都不能满足分配需求,那么此时唯一能够做的就是直接向分配子申请更多的空间。至于分配子如何去分配,是从池中获取还是直接调用malloc分配,此处不再讨论。

node->free_index = 0;

mem = node->first_avail;

node->first_avail += size;

list_insert(node, active);

pool->active = node;

free_index = (APR_ALIGN(active->endp - active->first_avail + 1,

BOUNDARY_SIZE) - BOUNDARY_SIZE) >> BOUNDARY_INDEX;

active->free_index = (APR_UINT32_TRUNC_CAST)free_index;

node = active->next;

if (free_index >= node->free_index)

return mem;

一旦获取到分配的新的结点,那么下一步就是从该结点中分配需要的size大小的空间,由mem指针指向该空间首地址。同时将该结点立即插入到actie链表中作为首结点。插入通过宏list_insert实现:

#define list_insert(node, point) do {

node->ref = point->ref;

*node->ref = node;

node->next = point;

point->ref = &node->next;

} while (0)

前面我们说过,active链表的第一个结点肯定是空闲空间最大的结点。尽管从池中刚分配的时候,node结点的空闲空间确实是最大,但是一旦分配了size大小之后则情况未必,因此node作为第一个结点存在可能是不合适的,为此必须进行适当的调整。

1)、如果新插入结点node的空闲空间确实比后继结点node->next的空间大,那么此时,毫无疑问,node是所有结点中空闲空间最大的结点,物归其所,不需要再调整。

do {

node = node->next;

}

while (free_index < node->free_index);

list_remove(active);

list_insert(active, node);

2)、如果node的空间比node->next的空间小,那么意味着node放错了地方,为此必须从node->next开始往后遍历找到合适的位置,并从原位置移出,插入新位置。

关于作者

张中庆,目前主要的研究方向是嵌入式浏览器,移动中间件以及大规模服务器设计。目前正在进行Apache的源代码分析,计划出版《Apache源代码全景分析》上下册。Apache系列文章为本书的草案部分,对Apache感兴趣的朋友可以通过flydish at sina.com.cn与之联系!

如果你觉得本文不错,请点击文后的“推荐本文”链接!!

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有