官方概述
Boost.Pool 是一个库,其中包含一些用于管理内存的类。虽然 C++ 程序通常用于 new
动态分配内存,但内存提供方式的详细信息取决于标准库的实现和操作系统。例如,使用 Boost.Pool,您可以加速内存管理,从而更快地为程序提供内存。
Boost.Pool 不会更改操作系统的行为 new
。Boost.Pool 之所以能正常工作,是因为首先从操作系统请求托管内存 - 例如,使用 new
.从外部来看,您的程序已经分配了内存,但在内部,内存还不是必需的,而是交给 Boost.Pool 来管理它。
Boost.Pool 使用相同的大小对内存段进行分区。每次您从 Boost.Pool 请求内存时,库都会访问下一个空闲段,并将该段的内存分配给您。然后,无论该段实际需要多少字节,整个段都会被标记为已使用。
这种内存管理概念称为简单隔离存储。这是 Boost.Pool 支持的唯一概念。如果必须频繁创建和销毁许多相同大小的对象,则此功能特别有用。在这种情况下,可以快速提供和释放所需的内存。
Boost.Pool 的内存池
boost::simple_segregated_storage SSS:
-
这是实现简单分段存储概念的底层类。
-
它允许你添加内存块,并分配和释放固定大小的内存段。
boost::object_pool:
-
这个类建立在 boost::simple_segregated_storage 之上,用于管理特定类型对象的内存。
-
它会自动分配和释放内存,无需你直接管理内存块。
-
你可以指定初始和最大内存块大小。
boost::singleton_pool:
-
这个类与 boost::object_pool 类似,但内存块大小在模板参数中指定,而不是在运行时配置。
-
它提供了使用不同"标签"创建多个内存池的方式。
-
它还允许你释放或清除内存回到操作系统。
boost::pool_allocator 和 boost::fast_pool_allocator:
-
这些是可以用于标准库容器(如
std::vector
和std::list
)的分配器类。 -
它们内部使用 Boost.Pool 类来管理内存分配和释放。
-
boost::pool_allocator
更适合于连续内存分配,而boost::fast_pool_allocator
更适合于单个内存分配。
SSS内存池
boost::simple_segregated_storage
是 Boost 库提供的一个底层的内存管理工具。它主要用于管理和分配内存块,为上层的内存池实现提供支持。
boost::simple_segregated_storage
的主要功能如下:
-
内存块管理:
- 它维护一个包含多个内存块的列表。
- 每个内存块都是一片连续的内存区域。
- 提供了添加、查找和删除内存块的接口。
-
内存分配:
- 根据请求的大小从内存块列表中分配内存。
- 如果找不到合适的内存块,则分配一个新的内存块。
- 支持对齐要求,确保分配的内存满足特定的对齐要求。
-
内存回收:
- 将已分配的内存块重新放回到内存块列表中。
- 合并相邻的空闲内存块,减少内存碎片。
-
线程安全:
- 提供了基于
std::mutex
的同步机制,支持多线程访问。
- 提供了基于
总结:
boost::simple_segregated_storage
(有点类似SGI二级内存管理,这里是用一个指针来管理)的主要特点包括:
- 简单轻量:它是一个基础的内存管理工具,实现简单,开销较小。
- 高效:通过维护内存块列表,可以快速分配和回收内存。
- 可定制:提供了许多可配置的选项,如内存块大小、对齐方式等。
- 可重用:可以被上层的内存池实现 (如
boost::pool
) 重复利用。
使用示例
// simple_segregated_storage 底层封装接口,基本不怎么使用。 默认对齐方式是按照256字节对齐的
boost::simple_segregated_storage<std::size_t> storage;
std::vector<char> v(1024);
storage.add_block(&v.front(), v.size(), 256); // 起始点 长度 每块大小
int *i = static_cast<int *>(storage.malloc());
*i = 1;
int *j = static_cast<int *>(storage.malloc_n(1, 512)); // 使用了2块内存块 512字节内存
j[10] = 2;
storage.free(i);
storage.free_n(j, 1, 512);
object_pool
除了sss内存池特点外,主要特点:
固定大小对象管理:
boost::object_pool
专注于管理固定大小的对象。- 它使用一个连续的内存块来存储这些对象,提高了空间利用率和缓存命中率。
线程安全支持:
boost::object_pool
提供了基于std::mutex
的同步机制,支持多线程环境下的安全使用。
异常安全:
boost::object_pool
的接口设计考虑了异常安全性。- 即使在分配或释放对象过程中发生异常,也不会导致内存泄漏。
#include <boost/pool/object_pool.hpp>
#include <boost/pool/singleton_pool.hpp>
#include <boost/pool/pool_alloc.hpp>
#include <vector>
#include <list>
#include <iostream>
class Myclass
{
private:
/* data */
public:
int value;
Myclass(/* args */)
{
}
Myclass(int v) : value(v)
{
}
~Myclass()
{
}
};
int main()
{
// 高级接口 自动分配内存,而无需您自己分配内存。 扩容:两倍 第二构造参数:最大扩容量
boost::object_pool<Myclass> classPool;
Myclass *obj1 = classPool.construct(10);
auto obj2 = classPool.construct(2);
std::cout << "obj1 :" << obj1->value << " obj2 " << obj2->value << std::endl;
// classPool.destroy(obj1);
// classPool.destroy(obj2);
// 初始内存块32个int 下次内存块则是64int 0则表示无最大扩容了 无限增长
boost::object_pool<int> boostTestpool{32, 10240};
boostTestpool.construct();
std::cout << "下一块内存块大小:" << boostTestpool.get_next_size() << "\n";
boostTestpool.set_next_size(8); // 设置下一块内存块大小
std::cout << "下一块内存块大小:" << boostTestpool.get_next_size() << "\n";
return 0;
}
singleton_pool
与object特点具有相同特性,主要特点:
-
单例模式:
-
全局共享:由于采用了单例模式,boost::singleton_pool 实例可以被全局共享使用。
-
静态接口:
boost::singleton_pool
提供了一组静态成员函数来管理内存池。- 这些静态接口可以直接通过类名调用,而不需要创建实例对象。
// 模板参1是标签 参2是类型 根据标签为索引的单例模式,线程安全。
using IntPool = boost::singleton_pool<struct IntPoolTag, sizeof(int)>;
int *i2 = static_cast<int *>(IntPool::malloc());
*i2 = 100;
int *j2 = static_cast<int *>(IntPool::ordered_malloc(10));
j2[9] = 2;
std::cout << "*i: " << *i2 << " j[9]" << j2[9] << std::endl;
std::free(i2);
// IntPool::release_memory(); //释放当前未使用的所有内存块
// IntPool::purge_memory(); // 释放所有内存块 - 包括当前正在使用的内存块。
Allocator内存分配器
boost::pool_allocator 和 boost::fast_pool_allocator 主要特点:
-
这些是可以用于标准库容器(如
std::vector
和std::list
)的分配器类。 -
它们内部使用 Boost.Pool 类来管理内存分配和释放。
-
boost::pool_allocator
更适合于连续内存分配,而boost::fast_pool_allocator
更适合于单个内存分配。
#include <boost/pool/object_pool.hpp>
#include <boost/pool/singleton_pool.hpp>
#include <boost/pool/pool_alloc.hpp>
#include <vector>
#include <list>
#include <iostream>
//定义宏 BOOST_POOL_NO_MT ,则禁用对 Boost.Pool 的多线程支持。
class Myclass
{
private:
/* data */
public:
int value;
Myclass(/* args */)
{
}
Myclass(int v) : value(v)
{
}
~Myclass()
{
}
};
struct IntPoolTag
{
};
struct VecIntPoolTag
{
};
int main()
{
// 使用 boost::pool_allocator 管理 std::vector 内存 pool_allocator基于singleton
std::vector<int, boost::pool_allocator<int>> vec;
for (int i = 0; i < 1000; ++i)
vec.push_back(i);
vec.clear();
boost::singleton_pool<boost::pool_allocator_tag, sizeof(int)>::
purge_memory();
// 使用 boost::fast_pool_allocator 地址不连续情景
using ListAllocator = boost::fast_pool_allocator<int, //分配器管理的对象类型
boost::default_user_allocator_new_delete, //内存分配器
boost::details::pool::default_mutex, //默认的互斥锁
64, 128>; //内存块的初始大小(以字节为单位)和最大大小
std::list<int, ListAllocator> l;
for (int k = 0; k < 1000; ++k)
{
l.push_back(k);
}
// l.clear();
// 重置所有使用 boost::fast_pool_allocator 分配器的内存池。
boost::singleton_pool<boost::fast_pool_allocator_tag, sizeof(int)>::purge_memory();
return 0;
}
总结
-
内存池管理:
- Boost.Pool 提供了两种主要的内存池实现:
boost::object_pool
和boost::singleton_pool
。 - 它们都利用
boost::simple_segregated_storage
来管理内存块,提高内存利用率和缓存命中率。
- Boost.Pool 提供了两种主要的内存池实现:
-
固定大小对象管理:
- Boost.Pool 专注于管理固定大小的对象,这种设计能够提高内存管理的效率。
- 它使用连续的内存块来存储这些对象,避免了频繁的
new
和delete
操作。
-
高效的内存分配和释放:
- Boost.Pool 采用了空闲链表的方式管理空闲对象,分配和释放对象只需要操作链表,开销较小。
-
线程安全支持:
- Boost.Pool 提供了基于
std::mutex
的同步机制,支持多线程环境下的安全使用。 - 定义宏 BOOST_POOL_NO_MT ,则禁用对 Boost.Pool 的多线程同步支持。
- Boost.Pool 提供了基于
-
自定义内存管理:
- Boost.Pool 允许用户自定义内存块的分配和释放行为,通过重载
malloc
和free
接口实现。
- Boost.Pool 允许用户自定义内存块的分配和释放行为,通过重载
-
异常安全:
- Boost.Pool 的接口设计考虑了异常安全性,即使在分配或释放对象过程中发生异常,也不会导致内存泄漏。
-
boost::pool_allocator
和boost::fast_pool_allocator
:- 这两种分配器实现了标准
std::allocator
接口,可以与标准容器和算法无缝集成。 - 它们利用了 Boost.Pool 的内存池机制,在需要频繁创建和销毁同一类型对象的场景下能够提高性能。
- 这两种分配器实现了标准