我试图了解boost :: pool块预分配的策略。我读了this和this提升文档,但是如果有可能的话我仍然不清楚在实例化池时请求特定的初始数量的预分配块。当我说“块”时我的意思是chunk = sizeof(SomeType) 例如,我做了这个测试:
foo.h中
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 :: pool大小的两倍,因为我还在不同的地方分配了其他池,块大小从4到16 mb不等。仅此一个池就是64 mb并查看Windows任务管理器(不是调查内存的最佳工具......)我看到总内存消耗大约是78 mb。这让我认为boost :: pool不会分配块大小65536,至少不是第一次。这是真的吗?如果是的话,是否意味着我需要包装我自己的池以允许这样的功能?因为我没有在池中找到任何允许其他方式的东西这样做。
PS:如果我删除了池,我看到进程使用的内存量几乎相同,这可能意味着boost :: pool分配了一个非常小的块。
答案 0 :(得分:1)
我试图了解boost :: pool块的策略 预分配。我读了这个以及这个提升文档,但它仍然没有 如果有可能请求特定的初始编号,请告诉我 在实例化池时预先分配的块。
不,这是不可能的,除非您编写自己的分配器,这可能会保留一些默认值。
这里解释了简单隔离存储的关键/本质(从here剪断):
简单的隔离存储也非常快。在最简单的 在这种情况下,内存分配只是从中移除第一个块 自由列表,O(1)操作。在空闲列表为空的情况下, 可能必须获取和分区另一个块 导致摊销的O(1)时间。内存释放可能很简单 将该块添加到空闲列表的前面,进行O(1)操作。 但是,简单隔离存储的更复杂用途可能 需要一个排序的空闲列表,这使得重新分配O(N)。
由此可以看出,当没有空闲块时(即空闲列表为空时),boost池会根据需要分配内存。因此,可能没有预先分配(或非常少),但是一旦分配了一些内容,释放和重新分配的速度非常快(因为在池超出范围之前,它实际上永远不会被释放)。
然后我不明白为什么他们提供那个“nextsize”param。它是否保证至少下一个块分配将等于那个大小?
分配器使用使用适用标记类型的singleton_pool实例,具体取决于分配器类型。 Singleton_pool实例化池的实例,并且从池源可以看出:
PS:如果我删除了池,我看到进程使用的内存量几乎相同,这可能意味着boost :: pool分配了一个非常小的块。
是的,它使用参数next_size来分配第一次,可能不会大于max_size