什么';boost::pool<>;::malloc和boost::pool<>;::我应该在什么时候使用boost::pool<>;::马洛克?

什么';boost::pool<>;::malloc和boost::pool<>;::我应该在什么时候使用boost::pool<>;::马洛克?,boost,pool,Boost,Pool,我正在使用boost.pool,但我不知道何时使用boost::pool::malloc和boost::pool::ordered_malloc 所以 boost::pool::malloc和boost::pool::ordered_malloc有什么区别 我应该什么时候使用boost::pool::ordered_malloc 首先,我们应该了解Boost池库背后的基本思想:简单隔离存储,它类似于单链表,负责将内存块划分为固定大小的块: 内存池保留内存块的可用列表。所以我们提到了块和块:内存

我正在使用boost.pool,但我不知道何时使用
boost::pool::malloc
boost::pool::ordered_malloc

所以

  • boost::pool::malloc
    boost::pool::ordered_malloc
    有什么区别

  • 我应该什么时候使用
    boost::pool::ordered_malloc


  • 首先,我们应该了解Boost池库背后的基本思想:
    简单隔离存储
    ,它类似于单链表,负责将内存块划分为固定大小的块:

    内存池保留内存块的可用列表。所以我们提到了块和块:内存池使用
    new
    malloc
    分配内存块,并将其划分为许多大小相同的内存块。
    假设地址按8,4字节对齐,用于存储下一个块的地址,因此内存块(8字节*32个块)如下所示(内存地址仅用于说明问题,而不是真实地址):

    现在,假设用户分配了两次8字节内存,因此使用了块:[0xDD00,0xDD08],[0xDD08,0xDD10)。一段时间后,用户在[0xDD00,0xDD08]处释放内存,因此该块将返回空闲列表。现在该块如下所示:


    在用户释放[0xDD08,0xDD10]处的内存之后,将该块放回列表中的最简单方法是首先更新
    以指向它,时间复杂度恒定。
    simple\u separated\u storage::free()
    正是这样做的:

    void free BOOST_PREVENT_MACRO_SUBSTITUTION(void * const chunk)
    { //! Free a chunk.
      //! \pre chunk was previously returned from a malloc() referring to the same free list.
      //! \post !empty()
       BOOST_POOL_VALIDATE_INTERNALS
      nextof(chunk) = first;
      first = chunk;
      BOOST_POOL_VALIDATE_INTERNALS
    }
    
    之后,列表将如下所示:

    现在我们注意到,在这些操作之后,块列表不是按地址排序的! 如果要在取消分配时保留顺序,请调用
    pool::ordered\u free()
    而不是
    pool::free()
    以正确的顺序将内存放回列表中。现在我们已经知道内存池中的顺序,让我们深入研究
    boost::pool::malloc
    boost::pool::ordered\u malloc
    的源代码:

    void * malloc BOOST_PREVENT_MACRO_SUBSTITUTION()
    {
      if (!store().empty())
        return (store().malloc)();
      return malloc_need_resize();
    }
    
    void * ordered_malloc()
    {
      if (!store().empty())
        return (store().malloc)();
      return ordered_malloc_need_resize();
    }
    
    正如我们所看到的,它们只有在内存块列表中没有空闲块时才有所不同。在这种情况下,它分配一个新内存块,将其空闲列表合并到池的空闲列表中,这两种方法之间的区别在于
    boost::pool::ordered\u malloc
    在合并空闲列表时保留顺序。
    以上是问题1。
    那么,为什么顺序很重要?!内存池似乎可以完美地处理无序的块!
    首先,如果我们想找到一个由n个块组成的连续序列,有序的自由列表将使它变得更容易。其次,让我们看看
    boost::pool
    boost::object\u pool
    ,它在销毁
    object\u pool
    对象时自动销毁未解除分配的对象,同时还可以手动重新旋转对象,例如:

    class X { … };
    
        void func()
        {
            boost::object_pool<X> alloc;
    
            X* obj1 = alloc.construct();
            X* obj2 = alloc.construct();
            alloc.destroy(obj2);
        }
    
    它遍历内存块列表中的所有块(
    list
    ,boost::pool的数据成员,保存从系统分配的所有内存块的位置和大小)要确定其中是否有块也显示在空闲列表中,如果没有,则调用对象的析构函数,然后释放内存。因此,这就像获得两个集合的交集一样!如果对列表进行排序,则执行此操作的速度会快得多。实际上,在
    boost::object\u pool
    中,顺序是必需的,public member fun操作:
    boost::object\u pool::malloc()
    boost::object\u pool::free()
    只需分别调用
    boost::pool::ordered\u malloc()
    boost::pool::ordered\u free()

    element_type * malloc BOOST_PREVENT_MACRO_SUBSTITUTION()
    { //! Allocates memory that can hold one object of type ElementType.
      //!
      //! If out of memory, returns 0. 
      //!
      //! Amortized O(1).
      return static_cast<element_type *>(store().ordered_malloc());
    }
    void free BOOST_PREVENT_MACRO_SUBSTITUTION(element_type * const chunk)
    { //! De-Allocates memory that holds a chunk of type ElementType.
      //!
      //!  Note that p may not be 0.\n
      //!
      //! Note that the destructor for p is not called. O(N).
      store().ordered_free(chunk);
    }
    
    element\u type*malloc BOOST\u PREVENT\u MACRO\u SUBSTITUTION()
    {//!分配内存,该内存可以容纳一个ElementType类型的对象。
    //!
    //!如果内存不足,则返回0。
    //!
    //!摊销O(1)。
    返回静态_cast(store().ordered_malloc());
    }
    无效的增强防止宏替换(元素类型*常量块)
    {//!De分配内存,该内存包含ElementType类型的块。
    //!
    //!请注意,p可能不是0。\n
    //!
    //!请注意,p的析构函数未调用.O(N)。
    store().已订购的\u free(块);
    }
    
    因此对于queston 2:在大多数情况下,您不需要使用
    boost::pool::ordered_malloc

    element_type * malloc BOOST_PREVENT_MACRO_SUBSTITUTION()
    { //! Allocates memory that can hold one object of type ElementType.
      //!
      //! If out of memory, returns 0. 
      //!
      //! Amortized O(1).
      return static_cast<element_type *>(store().ordered_malloc());
    }
    void free BOOST_PREVENT_MACRO_SUBSTITUTION(element_type * const chunk)
    { //! De-Allocates memory that holds a chunk of type ElementType.
      //!
      //!  Note that p may not be 0.\n
      //!
      //! Note that the destructor for p is not called. O(N).
      store().ordered_free(chunk);
    }