AutoFreeAlloc
概览
AutoFreeAlloc是一个最袖珍的GC Allocator。主要针对于局部的复杂算法。为这些局部复杂算法提供内存管理能力,使得C++程序员也可以象GC语言的程序员一样,可以全力关注于业务逻辑本身,而不被繁琐的内存管理细节所困扰。
AutoFreeAlloc的实现细节,请参考《C++内存管理变革(2):最袖珍的垃圾回收器 - AutoFreeAlloc》。这个GC Allocator获得了很大的成功,被广泛应用到我们实际的项目中。 当然,AutoFreeAlloc也有其天然的缺陷,需要理解什么情况下可以用它,而什么情况下不能用它(请参阅《C++内存管理变革(3):另类内存管理 - AutoFreeAlloc典型应用》)。在不能用AutoFreeAlloc的情形下,你可以考虑用ScopeAlloc。
规格
template <class _Policy> class AutoFreeAllocT { public: typedef typename _Policy::allocator_type allocator_type; enum { MemBlockSize = _Policy::MemBlockSize }; enum { HeaderSize = sizeof(void*) }; enum { BlockSize = MemBlockSize - HeaderSize }; enum { IsAutoFreeAllocator = 1 }; public: AutoFreeAllocT(); explicit AutoFreeAllocT(_Alloc alloc); explicit AutoFreeAllocT(AutoFreeAllocT& owner); ~AutoFreeAllocT(); // 析构,将调用clear()清理内存 void winx_call swap(AutoFreeAllocT& o); // 交换两个AutoFreeAlloc实例 void winx_call clear(); // 清除由该类管理的所有对象(对象的析构亦被调用) template <class Type> void winx_call destroy(Type* obj); // 空操作 template <class Type> Type* winx_call newArray(size_t count, Type* zero); // 创建数组 template <class Type> void winx_call destroyArray(Type* array, size_t count); // 空操作 void* winx_call allocate(size_t cb); // 申请内存 void* winx_call allocate(size_t cb, DestructorType fn); // 申请内存,并指定析构函数 void* winx_call allocate(size_t cb, int fnZero); }; class StdAlloc { public: enum { MemBlockSize = MEMORY_BLOCK_SIZE }; typedef DefaultStaticAlloc allocator_type; }; typedef AutoFreeAllocT<StdAlloc> AutoFreeAlloc;
_Policy
- AutoFreeAlloc所采用的策略。规格如下:
class _Policy { public: typedef XXX allocator_type; enum { MemBlockSize = XXX }; }
allocator_type
class Allocator { public: Allocator(); Allocator(const Allocator& alloc); // 拷贝构造 void* allocate(size_t cb); // 申请内存 void deallocate(void* p); // 释放内存 void swap(Allocator& alloc); // 交换两个Allocator实例 };
- 请注意,Allocator被要求支持拷贝构造(一般真正的Allocator很难做到这一点)。所以,这里的Allocator通常只有两个可能:
- 全局内存Allocator。如:StdLibAlloc(即DefaultStaticAlloc), CoTaskAlloc, HeapMemAlloc(即DefaultDynamicAlloc)等等。
- Allocator的代理。参见ProxyAlloc。
MemBlockSize
- AutoFreeAlloc中的MemBlock大小,它是AutoFreeAlloc性能调配的重要参数。默认我们给了一个经验值:MEMORY_BLOCK_SIZE。
构造函数
AutoFreeAllocT();
explicit AutoFreeAllocT(_Alloc alloc);
explicit AutoFreeAllocT(AutoFreeAllocT& owner);
alloc
- 指出AutoFreeAlloc应该从那个alloc实例中分配MemBlock。请注意,AutoFreeAlloc并不直接使用该alloc,而是执行一次拷贝构造。这通常要求_Alloc是一个全局内存Allocator,或者是一个Allocator代理。详细参加上面对_Alloc的注解。
owner
- 该AutoFreeAlloc的逻辑拥有者(Owner)。但是其实两者并无真正意义上的父子关系,新构造出来的AutoFreeAlloc实例只是用owner中的alloc成员拷贝构造了一份而已(从这个意义上来讲,两者更像是兄弟^_^)。
swap - 交换两个AutoFreeAlloc实例
void winx_call swap(AutoFreeAllocT& o);
o
- 要交换的AutoFreeAlloc实例。
clear - 清除管理的所有对象
void winx_call clear(); // 清除由该类管理的所有对象(对象的析构亦被调用)
注意
- 谨慎!该函数应在确保该AutoFreeAlloc所分配的所有对象都不再需要的情形下调用。
destroy - 空操作
template <class Type> void winx_call destroy(Type* obj);
- 该函数本意是释放一个对象。但是由于AutoFreeAlloc并不支持单独释放一个对象,故此该函数实际上只是一个空操作。
newArray - 创建数组
template <class Type> Type* winx_call newArray(size_t count, Type* zero);
- 该函数用于创建一个元素类型为Type的数组。但我们并不推荐直接使用它,而是应该用STD_NEW_ARRAY来完成这件事。
destroyArray - 空操作
template <class Type> void winx_call destroyArray(Type* array, size_t count);
- 该函数本意是释放一个数组。但是由于AutoFreeAlloc并不支持单独去释放某些对象,故此该函数实际上只是一个空操作。
allocate - 申请内存
void* winx_call allocate(size_t cb); // 申请内存
void* winx_call allocate(size_t cb, DestructorType fn); // 申请内存,并指定析构函数
cb
- 要申请的内存大小。以字节数(byte)为单位。
fn
- 回收该内存需要调用的函数。通常它是一个类的析构函数。当然你也可以将它用作给一个特殊的内存结构提供特定的回收函数。
- 我们推荐析构函数只是一些乏味的内存释放(回收)操作。其实和[[[cn:GC]]语言一样,我们理论上并不需要有析构函数,如果一切内存都在GC Allocator掌握之中的话。但是在C++中这种想法并不现实:例如,我们假设用户在类A中使用std::vector,std::string等类。当一个类有了这些类的实例,哪怕用户没有写析构函数,但是一个隐含的析构被生成。如果我们只是释放类A的内存,而不执行其析构,那么内存泄漏就发生了。
void* winx_call allocate(size_t cb, int fnZero);
相关参考
- C++内存管理变革(2):最袖珍的垃圾回收器 - AutoFreeAlloc
- WinxGui使用指南之C++标准扩展(AutoFreeAlloc)
- ScopeAlloc (GC Allocator)
- STD_NEW, STD_NEW_ARRAY
- STD_ALLOC, STD_ALLOC_ARRAY
- STD_NO_DESTRUCTOR
使用样例
(todo)
page_revision: 16, last_edited: 1207403838|%e %b %Y, %H:%M %Z (%O ago)





