C++内存池(memory pool)管理

1.内存池

程序员在使用C++中的动态内存分配器时,new/delete, malloc/free等操作时,可能会出现以下问题:

  • Memory Leak:new一块空间,但中间抛出错误,最后没有释放成功,导致memory leak;这个问题可以采用智能指针auto_ptr, shared_ptr, unique_ptr来解决
  • Mismatching Operators:new和delete没有配对使用,如new数组时,没有调用delete [] array,一个ptr被多次delete等错误操作
  • Fragmentation:当多次调用new和delete时,会让heap上产生大量的外部碎片
  • Long execution time:new/delet操作或者库函数malloc/free有可能需要系统调用,那么操作的overhead就会比较大
new/delete的一个显著特征是:new会分配一块内存空间,并调用构造函数对这块空间进行初始化。delete会首先调用对象的析构函数,然后再释放空间。

那么如果我们一开始分配一块大的空间buffer,然后从buffer中进行分配小的空间,并负责回收,这就是内存池的思想:
  • 预先申请好一块内存区域,并把它分成定长的块,当buffer中的内存不够时:使用类似vector的扩张方法,每次内存不够时,重新申请一块长度为已有内存两倍的内存块。
  • 每次需要内存申请时,将一块尚未分配的块返回。每次释放时,将传入的内存块重新标记为未分配。
定长内存池在工程中应用非常广泛。代码量少、效率高,非常适合用作大量同类型小数据的内存管理器。所谓定长内存池,就是buffer中的内存按固定长度进行分配和回收。

不同于定长内存池,不定长内存池可以在构造后申请各种不同大小的内存块。

实现方法:内部维护多个定长内存池,每次找到最小的能满足条件的内存池进行内存分配。如果申请的内存大于所有的内存池大小,则直接调用malloc()
如:分别维护1,2,4,8,16,32,64,128,256,512,1024bytes的定长内存池,对于每一个内存申请向上对齐到2的整次幂后分配对应大小的内存块,此时空间最多浪费一倍,效率低于定长内存池

2. SGI STL中的分配器
默认使用两级配置器
第一级配置器直接调用C的内存分配函数malloc()及realloc(),如果调用失败则执行oom_malloc()
第二级配置器的做法是,如果区块够大,超过128bytes时,就移交第一级配置器处理。当区块小于128bytes时,则以不定长内存池管理。
不定长内存池中维护16个定长内存池,大小分别为8,16,24,32,40,48,56,64,72,80,88,96,104,112,120,128bytes,将所需的内存向上对齐至8的倍数后交由对应的定长内存池分配
所有stl容器默认使用上述stl::alloc进行内存管理



 
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值