原地重新分配(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 < n; ++i) v.push_back(0); |
Metrowerks的Howard Hinnant一直在为实现应用于CodeWarrior标准库的原地扩展而努力,用他自己的话来说:
现在有一个可进行原地重新分配的vector<T, malloc_allocator<T>>,当Vec为一个不带原地扩展的vector<int>时,耗时为0.00095674秒;当Vec为一个带有原地扩展的vector<int>时,耗时为0.000416943。由此可看出,内存的原地重新分配,所带来的性能提升,非常之明显。
既然有了原地重新分配所带来的好处,而堆中的每个层都能控制其自己的分配算法和数据结构,请看下面的堆层接口:
| template <class T> struct Allocator : public T { void * malloc(size_t sz); void free(void* p); size_t expand(void* p, size_t min, size_t max); }; |
扩展在语义上的意思是,尝试通过p扩展指向在两者之间最大尺寸的块,并返回期望扩展的任意大小内存块。幸运的是,一个层不必关心用于扩展的子程序,如果所有顶层的分配方法都继承自以下的类,那么一切都将工作正常:
| struct TopHeap { size_t expand(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 | 速度不快,但碎片很少的堆 |
相关图文阅读
频道图文推荐
健 康 咨 询
时 尚 咨 询
相关专题
- 网络管理实用手册 (22210篇文章)
- C/C++技术专题 (1635篇文章)
- 揭秘Linux内存管理 (7881篇文章)
- C/C++进阶技术文档 (818篇文章)
- 用C语言编写Windows服务程序的五个步骤 (607次浏览)
- TCP/IP Winsock编程要点 (571次浏览)
- 新手看招 Linux操作系统下C++编程初探 (563次浏览)
- Visual C++实现Flash动画播放 (554次浏览)
- C++ 虚基类 (506次浏览)
- 用Visual C++在单文档界面中创建视图 (335次浏览)
- COM 组件设计与应用(一)起源及复合文件 (140次浏览)
- C++ Builder 初学问与答(四) (118次浏览)
- C程序实现汉字内码与GB码 (115次浏览)
- 确定一个应用程序是否没有响应 (115次浏览)



