内存池(MemPool)技术实例 - boost::pool

Boost Pool基于MemPool(内存池技术),用于快速分配同样大小的内存块,尤其是反复分配/释放同样大小的内存块的情况。相关的类主要有:

  • boost::pool
  • boost::object_pool
  • boost::singleton_pool
  • boost::pool_alloc

boost::pool

最基础的MemPool技术的实现。用于快速分配小块内存。如果pool无法提供小块内存给用户,返回NULL。样例:

void func()
{
    const int cbElement = sizeof(int); // 每次分配的块的大小。
    boost::pool<> alloc(cbElement);
    for (int i = 0; i < 10000; ++i)
    {
        int* p = (int*)alloc.malloc();
        // 不要奇怪这里没有指定要申请的内存大小,事实上内存池仅分配大小相同的内存块。
        // 所以,分配的字节数在构造pool组件的时候已经指定好了。
 
        ...
 
        alloc.free(p);
            // 释放内存块,交还给pool,不是返回给系统。
        // 如果愿意,你也可以不free该内存,pool组件析构时将清空管理的所有内存。
    }
}

boost::object_pool

boost::object_pool看似是boost::pool的对象化版本,但是其实他本质上和boost::pool完全不同:

从概念上讲,boost::object_pool属于非通用的GC Allocator(详细参考《C++内存管理变革(4):boost::object_pool与gc allocator》);而boost::pool则属于Allocator(虽然他并不符合STL的Allocator规范,但它仍然属于广义上的Allocator)。

从使用上来讲,boost::object_pool与boost::pool的区别在于:boost::pool指定每次分配的块的大小,boost::object_pool需要指定每次分配的对象的类型。(虽然偏于表象,但对用户来说确实如此)

从性能角度来讲,boost::object_pool并不是O(1)级的算法,比boost::pool慢很多。这一点详细还是要看《C++内存管理变革(4):boost::object_pool与gc allocator》。

使用样例:

class Obj { ... }; // has destructor with side-effects
 
void func()
{
    boost::object_pool<Obj> alloc;
    for (int i = 0; i < 10000; ++i)
    {
        void* mem = alloc.malloc();
        // 注意;X的构造函数不会被调用,仅仅是分配大小为sizeof(Obj)的内存块。
        // 如果需要调用构造函数(像new一样),应该调用construct。
        Obj* obj1 = new(mem) Obj(arg1, arg2, ...);
        // 调用了placement new,从而得到真正意义上的Obj类型的对象。
 
        Obj* obj2 = alloc.construct();
        ...
        alloc.destroy(obj2);
 
        // 你可以忘记释放obj1,boost::object_pool会记得这件事情。
    }
}

boost::singleton_pool

是boost::pool(内存池)的singleton模式的版本:boost::singleton_pool提供静态成员方法分配内存,不用定义allocator object。

样例:

struct MyPoolTag {};
 
typedef boost::singleton_pool<MyPoolTag, sizeof(int)> my_pool;
 
void func()
{
    for (int i = 0; i < 10000; ++i)
    {
        int* p = (int*)my_pool::malloc(); // 这里就和boost::pool不太一样了。
    }
    my_pool::purge_memory(); // 释放my_pool申请的所有内存
}

boost::pool_alloc

基于boost::singleton_pool实现,提供了满足STL Allocator规格Allocator

样例:

void func()
{
    std::vector<int, boost::pool_allocator<int> > v;
    for (int i = 0; i < 10000; ++i)
        v.push_back(13);
}

注意:

需要的话,必须自己显式地调用

boost::singleton_pool<boost::pool_allocator_tag, sizeof(int)>::release_memory();

把allocator分配的内存返回系统。

实现原理

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License