内存管理之内存池(boost)
2026/7/17 5:29:59 网站建设 项目流程

内存管理之内存池

1. pool 库概述

boost.pool 库基于简单分隔存储的思想实现了一个快速、紧凑的内存池库,不仅能够管理大量的对象,还可以用作 STL 的内存分配器。
在某种程度上讲,它类似一个小型的垃圾回收机制,在需要大量分配/释放小对象时其效率很高,而且完全不需要考虑delete

2. pool

pool是最简单、最容易使用的内存池类,其可以返回一个简单数据类型的内存指针。其需要包含的头文件如下<boost/pool/pool.hpp>

2.1 类摘要

pool的类摘要如下:

template<typenameUserAllocator=default_user_allocator_new_delete>classpool{public:// 构造函数和析构函数explicitpool(size_type requested_size);~pool();// 分配内存块的大小size_typeget_requested_size()const;// 分配内存void*malloc();void*ordered_malloc();void*ordered_malloc(size_type n);boolis_from(void*chunk)const;// 归还内存voidfree(void*chunk);voidordered_free(void*chunk);voidfree(void*chunk,size_type n);voidordered_free(void*chunk,size_type n);// 释放内存boolrelease_memory();boolpurge_memory();};

2.2 操作函数

pool的模板类型参数UserAllocator是一个用户定义的内存分配器,它实现了特定的内存分配算法,通常可以直接用默认的default_user_allocator_new_delete,它使用new[]delete[]分配内存。

pool构造函数可以接收一个size_type类型的整数requested_size,指示每次分配内存块的大小,这个值可以通过get_requested_size()获得。pool会根据需要自动地向系统申请或归还使用的内存,在析构时,pool将自动释放它所持有的所有内存。

成员函数malloc()ordered_malloc()的行为类似 C 中的全局函数malloc()malloc()从内存池中任意分配一个内存块,而ordered_malloc()则在分配的同时合并空闲块链表。ordered_malloc()带参数的形式可以连续分配 n 块内存。可以使用is_from()函数测试分配后的内存块是否从这个内存池分配出去的。

free()用于手动释放之前分配的内存块,这些内存块必须是从这个内存池分配出去的。

release_memory()让内存池释放所有未被分配的内存,但已分配的内存块不受影响;purge_memory()则强制释放pool持有的所有内存。

2.3 用法

  1. 代码示例
#include<iostream>#include<boost/pool/pool.hpp>// pool.cppintmain(){boost::poolpl(sizeof(int));// 一个可分配 int 的内存池// 必须把 void* 转换成需要的类型int*p=static_cast<int*>(pl.malloc());// 判断是否分配成功if(p!=nullptr){// 判断 p 是否来自于 plif(pl.is_from(p)){std::cout<<"内存块 p 来自 pl"<<std::endl;}}// 释放内存池分配的内存块pl.free(p);// 连续分配大量的内存for(inti=0;i<100;++i){pl.ordered_malloc(10);}return0;}
  1. 编译运行
# 编译g++-opool_demo pool.cpp# 运行./pool_demo

pool只能作为普通类型(如 int、double 等)的内存池,不能将其应用于复杂的类和对象,因为它只分配内存,不调用构造函数。调用构造函数时,我们需要使用object_poll

3. object_pool

object_pool是用于类实例(对象)的内存池,它的功能与pool类似,但会在析构时对所有已分配的内存块调用析构函数。其包含在头文件<boost/pool/object_pool.hpp>

3.1 类摘要

obejct_pool的类摘要如下:

template<typenameT,typenameUserAllocator>classobject_pool:protectedpool<UserAllocator>{public:typedefT element_type;object_pool();~object_pool();// 分配内存和归还内存element_type*malloc();voidfree(element_type*p);boolis_from(element_type*p)const;// 创建对象 和 销毁对象element_type*construct(...);voiddestory(element_type*p);};

3.2 操作函数

object_poolpool的子类,但它使用的是保护继承,因此不能使用pool的接口。

object_pool的特殊之处是construct()destory()函数。construct()实际上是一组函数,有多个参数的重载形式,其先调用malloc分配内存,再在内存块上使用传入的参数调用类的构造函数,返回的是一个已经初始化的对象指针。destroy()则先调用对象的析构函数,再用free释放内存块。

这些函数都不会抛出异常,如果内存分配失败,将返回 0(空指针)

3.3 用法

我们可以像pool那样使用object_pool分配原始内存块,也可以使用construct()直接在内存池中创建对象。

  1. 代码示例
#include<iostream>#include<boost/pool/object_pool.hpp>// object_pool.cpp// 示范用的类structdemo_class{public:inta,b,c;demo_class(intx=1,inty=2,intz=3):a(x),b(y),c(z){}};intmain(){// 对象内存池boost::object_pool<demo_class>pl;autop=pl.malloc();assert(pl.is_from(p));// p 指向的内存未经过初始化assert(p->a!=1||p->b!=2||p->c!=3);// construct 构造对象,可以传递参数p=pl.construct(7,8,9);std::cout<<p->a<<" "<<p->b<<" "<<p->c<<std::endl;// 定义一个分配 string 对象的内存池boost::object_pool<std::string>pls;// 连续分配大量 string 对象for(inti=0;i<10;++i){std::string*ps=pls.construct("hello object_pool");std::cout<<*ps<<std::endl;}return0;}
  1. 编译运行
# 编译g++-oobject_pool_demo object_pool.cpp# 运行./object_pool_demo

4. singleton_pool

singleton_poolpool接口完全一致,可以用它分配简单数据类型(POD)的内存指针,但它是一个“单件”。

“单件”指的是单例模式singelton_pool不需要创建对象,其把所有的接口都变成了静态函数,整个程序全局只有一个内存池实例。

singleton_pool默认使用 boost.thread 库提供线程安全保证,所以需要将它链接 boost_thread 库,如果不使用多线程,那么可以在头文件前
定义宏BOOST_POOL_NO_MT

4.1 类摘要

singleton_pool的类摘要如下所示:

template<typenameTag,unsignedRequestedSize>classsingleton_pool{public:staticboolis_from(void*ptr);// 分配内存staticvoid*malloc();staticvoid*ordered_malloc();staticvoid*ordered_malloc(size_type n);// 归还内存staticvoidfree(void*ptr);staticvoidordered_free(void*ptr);staticvoidfree(void*ptr,std::size_t n);staticvoidordered_free(void*ptr,std::size_t n);// 释放内存staticboolrelease_memory();staticboolpurge_memory();};

4.2 用法

singelton_poolpool的接口完全一致,但其成员函数是静态的,所以不需要声明singelton_pool的实例,直接使用域操作符::来调用静态
成员函数即可。

  1. 代码示例
#include<iostream>#include<boost/pool/singleton_pool.hpp>// 用于标记的空类structpool_tag{};// 第一个参数 Tag 用于标记不同的单件,可以是空类// 第二个参数 RequestedSize 等同于 pool 构造函数中的 requested_size,可以指示 pool 分配的内存块的大小typedefboost::singleton_pool<pool_tag,sizeof(int)>spl;// 定义内存池intmain(){// 分配一个整数内存块int*p=(int*)spl::malloc();// 释放内存spl::release_memory();return0;}
  1. 编译运行
# 编译g++-osingelton_pool_demo singelton_pool.cpp# 运行./singelton_pool_demo

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询