用C++实现对内存的管理(2)
2012/6/13 11:40:00 请友读忠(更多) E界MRP开发下载网 271阅 原地重新分配(Inplace Resizing)许多的C++程序员都梦寐以求有一种标准的原语(也即操作符),用于原地重新分配内存。众所周知,C语言中有realloc,其尽可能的原地重新分配内存,并在涉及到复制数据时使用memcpy,但memcpy并不适合于C++对象,所以,realloc也不适用于C++的对象。因此,任何一种renew原语都不能用标准C分配符来实现,这就是为什么C++中没有renew的原因。
以下演示了一种改进后的方法,可应用于C++代码中的原地重新分配,请看:
const int n = 10000;
Vec v;
for (int i = 0; i >,当Vec为一个不带原地扩展的vector时,耗时为0.00095674秒;当Vec为一个带有原地扩展的vector时,耗时为0.000416943。由此可看出,内存的原地重新分配,所带来的性能提升,非常之明显。
既然有了原地重新分配所带来的好处,而堆中的每个层都能控制其自己的分配算法和数据结构,请看下面的堆层接口:
template
struct Allocator : public T {
void * malloc(size_t sz);
void free(void* p);
size_t exp*(void* p, size_t min, size_t max);
};
扩展在语义上的意思是,尝试通过p扩展指向在两者之间最大尺寸的块,并返回期望扩展的任意大小内存块。幸运的是,一个层不必关心用于扩展的子程序,如果所有顶层的分配方法都继承自以下的类,那么一切都将工作正常:
struct TopHeap {
size_t exp*(void*, size_t, size_t) {
return 0;
}
protected:
“TopHeap() {}
};
结论
可配置的内存分配算符,是一种实用的、一体化的解决方案,可取代专门或通用的内存分配操作符。此外,HeapLayers的分层架构支持更简单的调试,并且具有非并行的可扩展性。表1演示了一个在HeapLayers中,层实现的相关子集,其中有许多值得讨论的地方,如多线程操作中的闭锁堆、STL适配程序、各种不同的工具堆、还有怎样结合多个层来创建一个通用的内存分配算符,另外,千万记住不要忘了在析构函数中释放内存,祝大家编程愉快!
表1:部分HeapLayers库
顶层堆 mallocHeap 取代malloc的层 mmapHeap 取代虚拟内存管理的层 sbrkHeap 取代sbrk(连续内存)构建块堆的层 AdaptHeap 使数据结构可作为堆使用 BoundedFreelistHeap 有长度限制的释放列表 ChunkHeap 以给定大小的块来管理内存 CoalesceHeap 执行拼接与拆分 FreelistHeap 一个释放列表(用于捕捉释放的对象) 组合堆 HybridHeap 对小对象使用一个堆,而对大对象使用另一个堆 SegHeap 用于分配方法的一般分割 StrictSegHeap 用于分配方法的严格分割 工具层 ANSIWrapper 提供与ANSI-malloc的兼容性 DebugHeap 检查多种分配错误 LockedHeap 为保证线程安全的闭锁堆 PerClassHeap 使用一个堆作为每个类的分配算符 PHOThreadHeap 带有自有分配算符私有堆 ProfileHeap 收集并输出碎片统计 ThreadHeap 一个纯私有堆分配算符 ExceptionHeap 当父类堆超出内存时,抛出一个异常 TraceHeap 输出有关内存分配的跟踪信息 UniqueHeap 引用一个堆对象的堆类型 对象表示 CoalesceableHeap 为拼接提供支持 SizeHeap 在头部中记录对象大小 特殊用途的堆 ObstackHeap 专门优化用于类似堆栈行为或快速大小调整的堆 ZoneHeap 一个区域分配算符 XallocHeap 优化用于类似堆栈行为的堆 通用堆 KingsleyHeap 快速但多碎片的堆 LeaHeap 速度不快,但碎片很少的堆
发表评论