【问题标题】:Can I use one memory pool for multiple vectors?我可以将一个内存池用于多个向量吗?
【发布时间】:2016-11-28 01:09:12
【问题描述】:

假设我有一个符合 STL(ish)的分配器。我希望 STL 容器 (std::vector) 的多个实例(数百万)使用该分配器的同一实例(我们假设线程安全得到保证)。这个实现会按预期工作吗?

MemoryPool<int> mypool;
std::vector<std::vector<int, MemoryPool<int>>> myvec;
myvec.assign(BIG_NUMBER, std::vector<int, MemoryPool<int>>{1, mydefault, mypool});

我也尝试过:

std::vector<std::vector<int, MemoryPool<int>>> myvec;
myvec.assign(BIG_NUMBER, {mydefault});

...并获得相同的内存使用情况。

问题是我的内存使用量随着这个实现而爆炸。从使用默认分配器的 ~12MB 到使用内存池分配器的 ~4GB。

我假设正在发生的事情是每个向量都获得了我的内存分配器的一个新实例,由于内存池的块大小很大,导致大量浪费存储。我的理由是,如果它们都使用相同的内存池实例,那么内存使用量会更接近默认分配器。

作为参考,我正在使用这个内存池实现:https://github.com/cacay/MemoryPool

【问题讨论】:

    标签: c++ memory-management stl


    【解决方案1】:

    您不能将上述MemoryPool 用作std::vector 的分配器,因为它用于固定大小的分配:

    内存池只有几个缺点:

    • 对象具有必须事先知道的固定大小。这通常不是一个 问题,如果您需要将它们分配成一堆,主要是这种情况。

    另见comment above the declaration of the allocate() function

    // Can only allocate one object at a time. n and hint are ignored
    pointer allocate(size_type n = 1, const_pointer hint = 0);
    

    std::vector 不满足此约束,因为它将内存分配为单个连续块,需要至少适合 capacity() 元素。因此它调用allocate() 函数,并将n 设置为capacity(),但MemoryPool 的工作方式就像传入了n=1MemoryPool 的实现甚至不提供保护(以断言)反对这种无效使用。

    【讨论】:

    • 有道理,为什么我不能为std::vector 使用这样的内存池。我知道在这种情况下有 UB,但我仍然怀疑实现使用了多少内存。源看起来将使用 less 内存,因为对多个类型 T 的请求将导致仅分配 1。
    • 作为我之前评论的补充,我怀疑向量会覆盖内存池中连续的、未分配的插槽,从而导致内存池对空闲/已用插槽的跟踪损坏。跨度>
    猜你喜欢
    • 1970-01-01
    • 2013-08-12
    • 1970-01-01
    • 2019-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多