boost::pool

boost::pool与内存池技术

转自:http://www.cnblogs.com/hujian/archive/2009/07/10/1520233.html


        Boost库的pool提供了一个内存池分配器,用于管理在一个独立的、大的分配空间里的动态内存分配。Boost库的pool主要适用于快速分配同样大小的内存块,尤其是反复分配和释放同样大小的内存块的情况。使用pool内存池主要有以下两个优点:
  1. 能够有效地管理许多小型对象的分配和释放工作,避免了自己去管理内存而产生的内存碎片和效率低下问题。
  2.  告别程序内存泄漏的烦恼,pool库会在内部对内存自动进行管理,避免了程序员一不小心而造成的内存泄漏问题。
      pool库主要提供了四种内存池接口,分别是pool、object_pool、singleton_pool和pool_allocator(fast_pool_allocator)。

   pool接口:头文件为<boost/pool/pool.hpp>,主要用于快速分配小块内存,使用时需要指定每次要分配的内存块的大 小。其malloc函数用于从内存池中分配内存;free函数用于释放内存,并交还给内存池,而不是系统;release_memory函数用于释放所有 未被分配的内存;purge_memory函数用于释放所有内存。当然,也可以不调用free或release_memory等函数,pool接口对象在 析构时会调用purge_memory自动释放所有内存。示例代码如下:

1        pool  <>    myPool(  sizeof  (  int  ));
2        for   (  int   i   =     0  ; i   <     10  ; i  ++  {
4           int   *pnNum  =  ( int   * )myPool.malloc();
5           *pnNum  =  i + 1 ;
6           cout  <<   *pnNum  <<  endl;
7      }

 

   object_pool接口:头文件为<boost/pool/object_pool.hpp>,顾名思义,主要用于对象的内存分配并自 动调用类的构造函数。其construct函数用于从内存池中分配内存并自动调用构造函数,其destroy函数用于释放内存交还给内存池并自动调用析构 函数。与pool接口一样,也可以不调用destroy函数,object_pool接口对象在析构时会自动释放所有内存并自动调用析构函数。另 外,object_pool接口也有malloc和free函数,但其malloc只分配内存而不负责构造,free只释放内存而不负责析构。因此,最好 将construct和destroy配对使用,将malloc和free配对使用,而不要两者混用。示例代码如下:

1           object_pool  <  CTest  >    myObjectPool;
2              for  ( int  j =   0; j <   10; ++j) {
4                CTest   *pTest   =   (CTest   *  )myObjectPool.construct(j  *  j);
5                  if   (j ==   5) {
7                   myObjectPool.destroy(pTest);
8                }
9            }

   singleton_pool接口:头文件为<boost/pool /singleton_pool.hpp>,singleton_pool接口的构造函数是私有的,因此不能够创建一个 singleton_pool接口的对象。singleton_pool接口提供了一些静态方法如malloc、free用于内存的分配和释放,其他方面 与pool接口相同。示例代码如下:

 1   struct   intpool { };
 2   struct   intpool2 { };
 3   typedef singleton_pool  <  intpool,   sizeof  (  int  )  >   ipool1;
 4   typedef singleton_pool  <  intpool2,   sizeof  (  int  )  >   ipool2;
 5         for   ( int   i   =     0  ; i   <     10    ++ i)  {
 7              int     *  q1   =   (  int     *  )ipool1::malloc();
 8              int     *  q2   =   (  int     *  )ipool2::malloc();
 9             *  q1   =   i;
10             *  q2   =   i  *  i;
11           cout   <<     *  q1   <<     "   and   "     <<     *  q2   <<   endl;
12        }
13        ipool1::purge_memory();
14        ipool2::purge_memory();

  pool_allocator接口:头文件为<boost/pool/pool_allocator.hpp>,主要与STL的容器一起使用,可用于代替STL中的allocator。示例代码如下:

1        vector  <  int  , pool_allocator  <  int  >     >    vctTemp;
2       list  <  char  , fast_pool_allocator  <  char  >     >    lstTemp;

    其中,pool_allocator的内部实现调用了ordered_malloc和ordered_free,可以满足对大量的连续内存块的分配请求。 fast_pool_allocator 的内部实现调用了malloc和free,比较适合于一次请求单个大内存块的情况,但也适用于通用分配,不过具有一些性能上的缺点。

 

 

 

 

 


 

转自:http://blog.csdn.net/xushiweizh/archive/2006/11/21/1400426.aspx

 

 

    Pool分配是一种分配内存方法,用于快速分配同样大小的内存块,
    尤其是反复分配/释放同样大小的内存块的情况。

1. pool


    快速分配小块内存,如果pool无法提供小块内存给用户,返回0。

    Example:

       void   func() {
        boost::pool  <>   p(   sizeof  (   int  ));
                        ^^^^^^^^^^^  
                      指定每次分配的块的大小
          for   ( int   i   =     0  ; i   <  10000   ++i) {
              int     * const   t   =   p.malloc();
                        pool分配指定大小的内存块;需要的时候,pool会向系统
                        申请大块内存。
            ...    //    Do something with t; don't take the time to free() it  
            p.free( t );
              //    释放内存块,交还给pool,不是返回给系统。  
        }
    }

      pool的析构函数会释放所有从系统申请到的内存。

 

2. object_pool   

 
    与pool的区别在于:pool需要指定每次分配的块的大小,object_pool需要指定
    每次分配的对象的类型。

    Example:
      struct   X { ... };   //   has destructor with side-effects 

    
  void   func() {
        boost::object_pool
  <  X  >   p;
                         
  ^ 
      
   for   (  int   i   =     0  ; i   <     10000    ++  i) {
           X 
  * const   t   =   p.malloc();
                      注意;X的构造函数不会被调用,仅仅是分配大小为sizeof(X)
                      的内存块。如果需要调用构造函数(像new一样),应该调用
                      construct。比如:
                      X 
  *     const   t   =   p.construct();
        ...
       }
    }

 

3. singleton_pool


    与pool用法一样。不同的是:可以定义多个pool类型的object,都是分配同样
    大小的内存块;singleton_pool提供静态成员方法分配内存,不用定义object。

    Example:

      struct   MyPoolTag { };

    typedef boost::singleton_pool
  <  MyPoolTag,   sizeof  (  int  )  >   my_pool;
    
  void   func() {
      
  for   (  int   i   =     0  ; i   <     10000    ++  i) {
        
  int     *     const   t   =   my_pool::malloc();
                        
  //   ^^^^^^^^^
                        
  //   和pool不一样。 
        ...
       }
      my_pool::purge_memory();
      
  //   释放my_pool申请的内存。 
    }

 

4. pool_alloc


    基于singleton_pool实现,提供allocator(用于STL等)。

    Example:

      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分配的内存返回系统。


实现原理


    pool每次向系统申请一大块内存,然后分成同样大小的多个小块,
    形成链表连接起来。每次分配的时候,从链表中取出头上一块,提
    供给用户。链表为空的时候,pool继续向系统申请大块内存。
    一个小问题:在pool的实现中,在申请到大块内存后,马上把它分
    成小块形成链表。这个过程开销比较大。即你需要分配一小块内存
    时,却需要生成一个大的链表。用如下代码测试:

boost::pool  <>   mem_pool(  16  );

for  (i   =     0  ; i   <   NPASS; i  ++  ) {
     period 
  =   clock();
  
  for  (n   =     0  ; n   <   NITEM; n  ++  ) {
   array_ptr[n] 
  =   (  int     *  )mem_pool.malloc();
  }
  
  for  (n   =     0  ; n   <   NITEM; n  ++  ) {
   mem_pool.free(array_ptr[n]);
  }
     period 
  =   clock()   -   period;
     printf(
  "  pool<>  : period = %5d ms  "  , period);
}

    可以发现,第一遍花的时间明显多于后面的。

    而且在pool的使用过程中如果不是恰好把链表中所有的小块都用上
    的话,在链表中最后的一些小块会始终用不上。把这些小块加入链
    表是多余的。虽然这个开销可能很小:)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值