分类: C/C++
2008-05-30 18:41:12
template struct Allocator : public T { void * malloc(size_t sz); void free(void* p); //系统相关的值 enum { Alignment = sizeof(double) }; //可选接口e size_t getSize(const void* p); }; |
struct MallocHeap { void * malloc(size_t sz) { return std::malloc(sz); } void free(void* p) { return std::free(p); } }; |
template class SizeHeap { union freeObject { size_t sz; double _dummy; //对齐所需 }; public: void * malloc(const size_t sz) { //添加必要的空间 freeObject * ptr = (freeObject *)SuperHeap::malloc(sz + sizeof(freeObject)); //请求的大小 ptr->sz = sz; return ptr + 1; } void free(void * ptr) { SuperHeap::free((freeObject *) ptr - 1); } static size_t getSize (const void * ptr) { return ((freeObject *)ptr - 1)->sz; } }; |
struct MallocHeap { ... 与上相同 ... size_t getSize(void* p) { return _msize(p); } }; |
template struct UseSizeHeap : public Super { static size_t getSize(const void * ptr) { return ((freeObject *) ptr - 1)->sz; } protected: union freeObject { size_t sz; double _dummy; //对齐所需 }; }; template class SizeHeap: public UseSizeHeap typedef typename UseSizeHeap freeObject; public: void * malloc(const size_t sz) { //添加必要的空间 freeObject * ptr = (freeObject *)SuperHeap::malloc(sz + sizeof(freeObject)); //存储请求的大小 ptr->sz = sz; return (void *) (ptr + 1); } void free(void * ptr) { SuperHeap::free((freeObject *)ptr - 1); } }; |
[NextPage]
现在,SizeHeap就会正确地添加UseSizeHeap层,并利用它的getSize实现了,而UseSizeHeap也能通过其他配置来使用--这是一个非常优雅的设计。
一个实用的示例:FreelistHeap
到目前为止,我们还处于一个准备的阶段,只有架构,还不知怎样利用这些层来编写一个高效专用的内存分配算符,也许一个比较合适的开发步骤可如下所示:
·收集有关程序为每种内存块大小进行分配次数的信息。
·为最经常请求的大小(在此称为S),维持一个私有、逐一链接的列表。
·对S的内存分配尽可能地从列表中返回内存,或者从默认分配算符中返回(在分层架构中,从上级层中)。
·对S大小内存块的释放,把内存块放回至列表中。
·一个精心设计的分配策略,应可对范围大小从S1至S2,使用相同的释放列表,并消耗同等的内存。而所需链接列表的操作开销为O(1),实际上只有几条指令。另外,指向下一条目的指针,能存储在实际的块中(块中存储了无用的数据--总为一个释放了的块),因此,对每个块就不需要额外的内存了。正因为大多数应用程序分配内存的大小都是不同的,所以,对任何分配算符的实现来说,释放列表就必不可少了。
下面让我们来实现一个层,由其对已知静态范围大小从S1至S2,实现了一个释放列表,见例3:
例3:
template struct FLHeap { ~FLHeap() { while (myFreeList) { freeObject* next = myFreeList->next; Super::free(myFreeList); myFreeList = next; } } void * malloc(const size_t s) { if (s < S1 || s > S2)) { return Super::malloc(s); } if (!myFreeList) { return Super::malloc(S2); } void * ptr = myFreeList; myFreeList = myFreeList->next; return ptr; } void free(void * p) { const size_t s = getSize(p); if (s < S1 || s > S2) { return Super::free(p); } freeObject p =reinterpret_cast p->next = myFreeList; myFreeList = p; } private: // 嵌入在释放的对象中的链接列表指针 class freeObject { public: freeObject * next; }; //释放的对象链接列表头 freeObject * myFreeList; }; |
typedef FLHeap< SizeHeap 24, 32> SmartoHeapo; |