Boost之内存池学习

来源:互联网 发布:c语言能做界面吗 编辑:程序博客网 时间:2024/06/05 09:08

     内存池简单意思就是 预先分配一个较大的内存空间,然后就可以在内存池里使用某种高效率的算法自定制内存分配。

      内存池是在真正使用内存之前,先申请分配一定数量的、大小相等(一般情况下)的内存块留作备用。当有新的内存需求时,就从内存池中分出一部分内存块,若内存块不够再继续申请新的内存。这样做的一个显著优点是尽量避免了内存碎片,使得内存分配效率得到提升。

    在内核中有不少地方内存分配不允许失败. 作为一个在这些情况下确保分配的方式, 内核开发者创建了一个已知为内存池(或者是 "mempool" )的抽象. 一个内存池真实地只是一类后备缓存, 它尽力一直保持一个空闲内存列表给紧急时使用.

   在boost库中,实现内存池的库是pool. 在这个库里包含了四个部分。 分别是pool,object_pool,singleton_pool以及pool_alloc.

    pool:

     是最简单也最容易使用的内存池库,可以返回一个简单类型的指针。

     头文件是: boost/pool/pool.hpp . 位于 boost命名空间。

     简单使用方法:

    boost::pool<> pl(sizeof(int));    参数为 内存池块的大小

    int *p=(int *)pl.malloc();          分配内存

    pl.free();       释放内存

    用法很简单,但是该类只能用作简单类型的内存分配,不能为复杂的类和对象分配。

object_pool:

  适用于类实例的内存池。   他是从pool类派生而来。 主要区别在于,在析构函数时,会调用类的析构函数,正确释放资源。

  头文件是: boost/pool/object_pool.hpp . 位于 boost命名空间。

 注意: 该类是从pool类派生而来,所以就继承了pool的 malloc,free等方法, 在使用这个内存池的时候,尽量不要调用malloc,free,因为调用malloc 可以正确分配内存,但是在调用free释放内存的时候,不会调用已分配内存块的析构函数。

   object_pool<string> opl;

  string *str=opl.malloc();      //use malloc fuction.

  p=opl.construct("ac");        //class object_pool特有的方法,实现内容是 先调用模版类型的构造函数,然后在调用malloc 分配内存。

  在程序结束时 调用object_pool的析构函数时就会调用模版类型的析构函数。

singleton_pool:

  跟pool类的接口完全一致,可以分配简单数据类型的指针。 但是它一个单间,提供线程安全。

  跟pool类的区别有:  虽然跟pool的接口完全一致,但是 它的成员函数都是静态的。 不需要声明实例,直接可以调用。所以它的生命周期跟程序一样长。  也因此它分配的内存,都不会自动释放,都要手动调用release_memory或者 purge_memory 释放内存,

模版参数: 有两个。  第一个是仅仅用于标记不同的单件,可以是空类,甚至是声明。 第二个参数就跟pool类的参数一样,指示内存块的大小。

 int *p=singleton_pool<struct pool_tag,sizeof(int) >::malloc();

singleton_pool<struct pool_tag,sizeof(int) >::release_memory();  释放所有未被分配的内存。 而已经分配的内存要知道程序结束才完全释放。

 由于这样使用的方式名字太冗长。  所以一般使用 typedef 简化名字。

  typedef singleton_pool<struct pool_tag,sizeof(int) > spl;

  以后在需要使用singleton_pool<struct pool_tag,sizeof(int) > 的时候直接使用 spl 就可以。

最后一个 pool_alloc:

 该类主要适用于 STL中,包含了两个可以用于STL的内存分配器。 pool_alloc 与 fase_pool_allocator 都位于名字空间 boost; t头文件在 boost/pool/pool_alloc.hpp

vector<int,pool_alloc<int> > v;       使用pool_alloc代替了 STL自己默认的内存分配器,一般只有在特殊需求才这样使用,否则还是使用STL自带,因为有可能pool_alloc 与 STL容器存在某些问题。 在使用前要仔细测试。

v.push_back(10);

 

 boost的内存池就介绍完了, 一般常用的就是前三个,但是object_pool最常用。

  内存池其实跟只能指针差不多, 很像小型的垃圾回收机制。  感觉跟智能指针很想像,区别就不知道,就因为内存池可以预先分配大一点的内存? 。 

0 0