内存池预先分配了一块大的内存空间,然后就可以在其中使用某种算法实现高效快速的自定制内存分配。
boost.pool 库基于简单分隔存储思想实现了一个快速、紧凑的内存池库,不仅能够管理大量的对象,还可以被用做STL的内存分配器。
它近似于一个小型的垃圾回收机制,在需要大量地分配/释放小对象时很有效率,而且完全不需要考虑 delete。
pool库包含四个组成部分:
- 最简单的 pool
- 分配类实例的 object_pool
- 单例内存池 singleton_pool
- 可用于标准库的 pool_alloc
一、pool
它只能用作普通的数据类型如 int、double 等的内存池,不能应用于复杂的对象,因为它只分配内存,不调用构造函数。
#include <boost/pool/pool.hpp>
using namespace boost;
int main()
{
//使用默认分配器,其内部使用new[]、delete[]分配内存
pool<> pl(sizeof(int));//分配int的内存池
int *p = static_cast<int*>(pl.malloc());//void*转成需要的类型
qDebug()<<"p是否来自内存池p1"<<pl.is_from(p);
pl.free(p);
int *p2 = new int;
qDebug()<<"p2是否来自内存池p1"<<pl.is_from(p2);
delete p2;
for (int i = 0;i < 100; ++i)
{
pl.ordered_malloc(10);//连续分配大量的内存
}
}//所有分配的内存被释放
二、object_pool
object_pool 是用于类实例(对象)的内存池,它的功能与pool类似,但会在析构时对所有已经分配的内存块调用析构函数,从而正确地释放资源。
#include <boost/pool/object_pool.hpp>
using namespace boost;
struct test
{
public:
int a,b,c;
test(int x = 1, int y = 2, int z = 3):a(x),b(y),c(z)
{}
};
int main()
{
object_pool<test> pl;
test * p = pl.malloc();
std::cout <<pl.is_from(p);
p = pl.construct(7, 8, 9);
object_pool<std::string> pls;
for (int i = 0; i < 10 ; ++i)
{
std::string *ps = pls.construct("hello object_pool");
std::cout << *ps << std::endl;
}
}
三、singleton_pool
singleton_pool 的接口和 pool 一致,但它的成员函数全是 static 的,它是个单例。
除非调用 release_memory() 或 purge_memory(),否则它不会自动释放所占内存。
其他都和 pool 一致。
#define BOOST_POOL_NO_MT //默认使用线程库保证安全,如果不使用多线程则定义此宏
#include <boost/pool/singleton_pool.hpp>
using namespace boost;
int main()
{
int *p = (int *)singleton_pool<int, sizeof(int)>::malloc();
singleton_pool<int, sizeof(int)>::release_memory();//释放所有未被分配的内存
// singleton_pool<int, sizeof(int)>::purge_memory();//强制释放内存池持有的所有内存
}
四、pool_alloc
pool_alloc 提供了两个可以用于标准容器模板参数的内存分配器,分别是 pool_alloc 和 fast_pool_allocator,它们的行为与之前的内存池类有一点不同:当内存分配失败时会抛出异常std::bad_alloc。
#include <boost/pool/pool_alloc.hpp>
using namespace boost;
int main()
{
std::vector<int, pool_allocator<int> > v;//使用pool_allocator代替默认的内存分配器
v.push_back(10);
std::cout << v.size();
}