我试图理解boost::pool块预分配的策略。我读了这篇文章,也读了这篇boost文档,但我仍然不清楚,当池实例化时,是否有可能请求特定初始数量的预分配块。我说的"chunk"是指chunk = sizeof(SomeType)例如,我做了这个测试:
foo。
class Foo
{
public:
typedef MAllocator<float> FloatPoolAllocator;
typedef std::shared_ptr<boost::pool<> > FloatPoolSP;
static FloatPoolSP _floatPoolSP;
static FloatPoolAllocator _floatAllocator;
std::vector<float, FloatPoolAllocator> data1;
std::vector<float, FloatPoolAllocator> data2;
std::vector<float, FloatPoolAllocator> data3;
};
Foo.cpp
std::shared_ptr<boost::pool<> > Foo::_floatPoolSP = std::shared_ptr<boost::pool<> >(new boost::pool<>(sizeof(uint8_t), 65536));
MAllocator<float> Foo::_floatAllocator = MAllocator<float>(_floatPoolSP);
Foo::Foo()
{
data1 = std::vector<float, FloatPoolAllocator>(_floatAllocator);
data2 = std::vector<float, FloatPoolAllocator>(_floatAllocator);
data3 = std::vector<float, FloatPoolAllocator>(_floatAllocator);
}
现在,我希望我的进程内存至少是指定的boost::池大小的两倍,因为我在不同的地方分配其他池,块大小从4到16 mb不等。这个池单独是64 mb,并查看Windows任务管理器(不是调查内存的最佳工具…)我看到总内存消耗大约是78 mb,这让我认为boost::pool没有分配65536的块大小,至少第一次没有。这是真的吗?如果是,这是否意味着我需要包装我自己的池来允许这样的功能?因为我还没有在池中找到任何允许另一种方式执行的方法。
PS:如果我删除池,我看到进程使用的内存量几乎相同,这再次可能意味着boost::pool分配了非常小的块。
我试图理解boost::pool块的策略预先分配。我读了这个,也是这个促进文件,但它仍然不是明确为我,如果有可能要求一个具体的初始数量池实例化时预分配的块。
不,这是不可能的,除非您编写自己的分配器,它可能会保留一些默认值。
简单隔离存储的关键/本质在这里解释(从这里剪辑):
简单隔离存储也非常快。用最简单的方法在这种情况下,内存分配只是从中删除第一个块一个O(1)的操作。在空闲列表为空的情况下,另一个块可能需要获取和分区,这将得到的平摊时间为O(1)。内存释放可能也很简单将该块添加到空闲列表的前面,这是一个O(1)操作。然而,简单隔离存储的更复杂的使用可能需要一个有序的空闲列表,这使得释放O(N)。
从这里可以看到,当没有空闲块存在时(即当空闲列表为空时),boost池按需要分配内存。因此,可能没有预分配发生(或者很少),但是一旦分配了一些东西,释放和重新分配非常快(因为本质上它永远不会真正释放,直到池超出作用域)。
那么我不明白为什么他们提供"nextsize"参数。是否保证至少下一个块分配将等于这个大小?
分配器使用适用标记类型的singleton_pool实例,具体取决于分配器的类型。Singleton_pool实例化了一个pool的实例,从pool的源代码中可以看到:
- max_size是分配给一个块的最大块数。
- next_size是对象第一次需要分配内存时请求的块的数量。
- 另一个参数( requestd_size )来自sizeof(T),被请求对象的大小。
PS:如果我删除池,我看到进程使用了几乎相同数量的内存量,这再次可能意味着boost::pool分配了非常小的块。
是的,它使用参数next_size来分配第一次,它可能不大于max_size