- 论坛徽章:
- 0
|
本帖最后由 Frahm 于 2013-01-26 02:48 编辑
我在看到侯捷的那本《STL 源码剖析》中allocator一章节,对它的实现思路基本了解了,也就是分两级,我主要对第二级,也就是默认的那个allocator的实现有些疑问,
大概说来它是这样的:对于较小的内存分配请求,采用预分配的链表的形式,以8的倍数大小为单位的内存区块(8,16,24,...128 ),每种大小都是一个链表,然后用一个数组把这些链表的头结点存起来,请求内存小于128bytes时就从数组找到对应的链表节点,如果该组链表结点不足,就从一个内部的heap划分出来20块请求大小的内存,加到链表中,再从链表取走一块用,当heap不够20块时,就直接分出去1块用,当一块都不够时(这个时候剩的大小一定也是8的倍数),就把零头全加入到合适大小的链表中去,然后malloc 大小为40块请求大小的内存,20块再和刚刚同样处理(加入合适的链表,分出去一块), 其余20块大小的chunk就留在heap里备用,问题就是他是怎么释放掉malloc的内存的,我只看到malloc了,第二级allocator的代码里没有看到free的字眼,其中的deallocate函数是这样的:- static void deallocate(void *p, size_t n)
- {
- obj *q = (obj*)p;
- obj * volatile * my_free_list;
- //大于 128 就呼叫第一级配置器
- if(n > (size_t) __MAX_BYTES) {
- malloc_alloc::deallocate(p, n);
- return;
- }
- // 寻找对应的free list
- my_free_list = free_list + FREELIST_INDEX(n);
- //调整free list 回收区块
- q -> free_list_link = *my_free_list;
- *my_free_list = q;
- }
复制代码 上面的那个malloc_alloc就是第一级allocator, 是针对较大内存分配时才使用的,所以对于在第二级自身malloc的内存,这个函数只是简单的把那块内存返还到了指定大小的链表中而已。
我感觉虽然不该在这里释放,但也总要释放的吧?是我看漏了哪里吗?难道sgi stl的实现中有另一个函数来做这种工作?
如果没有的话,针对这种情形应该如何释放呢?
所有的链表中的内存块都不是独立malloc的,而是一次malloc中的一部分,而且一次malloc的内存很可能分散在多组链表里,我现在想的,是用一个数据结构把每次malloc的内存块的指针保存下来,在最后的最后全部free掉,但是这样又比较危险,如果有对象正在使用这块内存。
是否是这种设计本身决定了不能随便释放内存呢,有没有其他方法可以比较灵活的紧缩/释放allocator占用的内存呢? |
|