基于小对象内存内存池的stl空间配置器__gnu_cxx::__pool_alloc

gun提供的拓展库里的基于stl的小对象内存内存池的空间配置器。可以适用于stl的所有容器。提供小对象分配的高速实现和减少内存碎片的解决方案。

使用方式如:

std::map<uint32,uint32,std::less<uint32>,__gnu_cxx::__pool_alloc<std::pair<uint32,uint32> > > EquipAttributesMap;//属性id:属性值

内存分配方式:

小于128字节的小对象的内存是从链表数组中获取,否则使用::operator new来申请内存。

回收内存方式:

小于128字节的小对象的内存是回收到链表数组中,否则使用::operator delete来释放内存。


源码如下:

定义:

template<typename _Tp>
    class __pool_alloc : private __pool_alloc_base

分配内存:

template<typename _Tp>
    _Tp*
    __pool_alloc<_Tp>::allocate(size_type __n, const void*)
    {
      pointer __ret = 0;
      if (__builtin_expect(__n != 0, true))
{
 if (__builtin_expect(__n > this->max_size(), false))
   std::__throw_bad_alloc();


 // If there is a race through here, assume answer from getenv
 // will resolve in same direction.  Inspired by techniques
 // to efficiently support threading found in basic_string.h.
 if (_S_force_new == 0)
   {
     if (getenv("GLIBCXX_FORCE_NEW"))
__atomic_add(&_S_force_new, 1);
     else
__atomic_add(&_S_force_new, -1);
   }


 const size_t __bytes = __n * sizeof(_Tp);     
 if (__bytes > size_t(_S_max_bytes) || _S_force_new == 1)
   __ret = static_cast<_Tp*>(::operator new(__bytes));
 else
   {
     _Obj* volatile* __free_list = _M_get_free_list(__bytes);
     
     lock sentry(_M_get_mutex());
     _Obj* __restrict__ __result = *__free_list;
     if (__builtin_expect(__result == 0, 0))
__ret = static_cast<_Tp*>(_M_refill(_M_round_up(__bytes)));
     else
{
 *__free_list = __result->_M_free_list_link;
 __ret = reinterpret_cast<_Tp*>(__result);
}
     if (__builtin_expect(__ret == 0, 0))
std::__throw_bad_alloc();
   }
}
      return __ret;
    }


回收内存:

template<typename _Tp>
    void
    __pool_alloc<_Tp>::deallocate(pointer __p, size_type __n)
    {
      if (__builtin_expect(__n != 0 && __p != 0, true))
{
 const size_t __bytes = __n * sizeof(_Tp);
 if (__bytes > static_cast<size_t>(_S_max_bytes) || _S_force_new == 1)
   ::operator delete(__p);
 else
   {
     _Obj* volatile* __free_list = _M_get_free_list(__bytes);
     _Obj* __q = reinterpret_cast<_Obj*>(__p);


     lock sentry(_M_get_mutex());
     __q ->_M_free_list_link = *__free_list;
     *__free_list = __q;
   }
}
    }




你可能感兴趣的:(基于小对象内存内存池的stl空间配置器__gnu_cxx::__pool_alloc)