标签:
STL的 __pool_alloc, __mt_alloc,boost的pool系列, ace的ACE_Cached_Allocator均为定长内存池。
内存池,根据存储的元素的长度是否可变,分为变长,与定长两种内存池。
从逻辑上来讲,定长内存池只需存储相同大小的元素,因此无须花费额外的空间(数据结构)来存储元素长度的信息。
以上几种定长内存池都可以较好的处理定长内存频繁分配的问题。
pool_alloc,原理是挂了16个链表(_S_free_list),每个链表存储分配大小为[1,8],[9-16],[17-24],...,[120,128]的数据。
1.下图(图一)为数据结构:
1 class __pool_alloc_base
2 {
3 protected:
4
5 enum { _S_align = 8 };
6 enum { _S_max_bytes = 128 };
7 enum { _S_free_list_size = (size_t)_S_max_bytes / (size_t)_S_align };
8
9 union _Obj
10 {
11 union _Obj* _M_free_list_link;
12 char _M_client_data[1]; // The client sees this.
13 };
14
15 static _Obj* volatile _S_free_list[_S_free_list_size];
16
17 // Chunk allocation state.
18 static char* _S_start_free;
19 static char* _S_end_free;
20 static size_t _S_heap_size;
21
22 ...
23 };2.下图(图二)为链表示意图:
3.allocate
__pool_alloc<_Tp>::allocate(size_type __n, const void*)
allocate时,该函数会根据请求的__n乘以sizeof(T)来计算,决定由哪个链表分配。
4.deallocate
__pool_alloc<_Tp>::deallocate(pointer __p, size_type __n)
这点需要重点注意,__n必须要传。如果__n的值与allocate分配时的大小不一致,将会导致deallocate失败。原因是__pool_alloc不会保存实际元素有多长,他需要根据__n来计算数据到底存于哪个链表。
mt_alloc实现相对复杂,我本地有一篇详细的文档,但由于篇幅的原因,不适宜在本文中添加。
定义
template<typename _Tp,typename _Poolp = __common_pool_policy<__pool, __thread_default> >class __mt_alloc : public __mt_alloc_base<_Tp>
说明
allocate和deallocate实际都是使用的__pool来分配和管理内存。
标签:
原文地址:http://www.cnblogs.com/onlyforcloud/p/4398138.html