性能优秀的内存池,服务器专用

 

 //==================================tls.h=====================================================================
#if !defined(__TLS_H__)
#define __TLS_H__

#ifdef _MSC_VER
 #include <wtypes.h>
 #include <malloc.h>
 typedef  unsigned long  tls_type;
 #define ctid() ::GetCurrentThreadId()
 #define mem_size(x)  _msize(x)
#else
 #include <pthread.h>
 #include <malloc.h>
 typedef pthread_key_t tls_type;
 #define ctid() pthread_self()
 #define mem_size(x)  malloc_usable_size(x)
#endif

 //中断应用
#define Breakpoint(T) { while (1) { printf("无效内存,程序中断...0x%08x...\r\n", (long)T); } }

class TlsIndex
{   
public:
 TlsIndex()
 {
#ifdef _MSC_VER
  m_index = TlsAlloc();
#else
  pthread_key_create(&m_index, NULL);
#endif
 }
 ~TlsIndex()
 {
#ifdef _MSC_VER
  ::TlsFree(m_index);
#else
  pthread_key_delete(m_index);
#endif
  
 }
public:
 operator tls_type() const
 {
  return m_index;
 }
private:
 tls_type m_index;
};

template<typename TDerived>
class TlsSingelton
{
 typedef TDerived _Derived;
 typedef TlsSingelton<TDerived> _Base;
 public:
 static _Derived* tlsInstance()
 {
  return tlsCreate();
 }
 protected:
 static _Derived* tlsCreate()
 {
  _Derived* derived = tlsGet();

  if ( derived )
   return derived;

  derived = new _Derived();
  //printf("=============tlsCreate(0x%08x)=================\r\n\r\n", derived);
 #ifdef _MSC_VER
  TlsSetValue(tlsIndex(), derived);
 #else
  pthread_setspecific(tlsIndex(), derived);
 #endif

  return derived;
 }
 static bool tlsDestroy()
 {
  _Derived* derived = tlsGet();

  if ( derived == NULL )
   return false;

  delete derived;
  
  return true;
 }
 static tls_type tlsIndex()
 {
  static TlsIndex s_tlsIndex;
  return s_tlsIndex;
 }
 private:
 static _Derived* tlsGet()
 {
 #ifdef _MSC_VER
  return reinterpret_cast<_Derived*>(::TlsGetValue(tlsIndex()));
 #else
  return reinterpret_cast<_Derived*>(pthread_getspecific(tlsIndex()));
 #endif
 }
 //noncopyable
private:
 TlsSingelton(const _Base&);
 TlsSingelton& operator=(const _Base&);
};

#endif

 

//==============================================================tls_pools.h===================================

#if !defined(__TLS_POOLS__)
#define __TLS_POOLS__

#ifdef _MSC_VER
#pragma warning(disable: 4200)
#pragma warning(disable: 4786)
#pragma warning(disable: 4355 4244 4267 4311 4312)
#endif

#include <time.h>

#include <map>
#include <list>
#include <algorithm>
using namespace std;

#include "tls.h"
#include "zn_log.h"

#if (_MSC_VER >= 1300)
#include <hash_map>
using namespace stdext;
#elif defined(__GCC__) || defined(_GNUC)
#include <ext/hash_map>
using namespace __gnu_cxx;
#endif

#if defined(_USE_HASH_MAP)
#define mymap     hash_map
#else
#define mymap     std::map
#endif //_USE_HASH_MAP

namespace BaseLib {

 const unsigned short buffer_mem_size  = 512;   //最小内存单位
 const unsigned short buffer_reserved  = 12;   //预留字节数,前4位识别码后8位对像指针
 const long    max_granule   = 0XF0000;  //256K

 inline int calculate_size(int nSize)
 {
  return nSize +
   (buffer_mem_size - (nSize % buffer_mem_size)) + buffer_reserved;
 }

 class CMemory
 {
  typedef struct tick_
  {
   tick_() :utick(0) {}
   unsigned long utick;
  }_tick;

  class Container
  {
  public:
   typedef list<CMemory*> pool_list;
   Container()
   {
    m_allpool = new pool_list;
    m_idle = new pool_list;
   }

   pool_list* m_allpool;
   pool_list* m_idle;
  };

  typedef mymap<unsigned long, Container*> MAP;

 private:
  CMemory(int nSize)
   : m_allocate_size(nSize)
  {
   //printf("new size=%d\t", nSize);

   //1.分配内存大小
   m_pData = (unsigned char*)calloc(1, nSize);

   //2.获取实际内存大小
   long _size = mem_size(m_pData);

   //3.写入内存标示
   long* position = (long*)&m_pData[_size - buffer_reserved];
   //保留字前4位为内存实际大小
   (*position) = _size;
   position++;
   //保留字后4位为所在对象指针  TODO:64BIT 需要修改
   (*position) = (const long)this;
   m_nCrtThreadID = ctid();
   m_nRefThreadID = 0;
  }

  ~CMemory()
  {
   free(m_pData);
  }

  unsigned char* buffer()
  {
   return m_pData;
  }

 public:
  static void* tls_malloc(unsigned long nSize, bool bCalculate = true)  //分配内存
  {
   //1.获取TLS内存对像,不存在则创建
   MAP* pMap = TlsSingelton<MAP>::tlsInstance();

   if (pMap == NULL)
    return NULL;

   _tick* tick = TlsSingelton<_tick>::tlsInstance();

   //===========================输出本线程内存块实用情况================================
   if (time(0) - tick->utick > 120)
   {
    double total_size = 0.0;
    for (MAP::iterator iter = pMap->begin(); iter != pMap->end(); ++iter)
    {
     c_znLog::_msg("线程ID=%8u, 块大小=%8d, 块数量=%8d, 空闲数量=%8d\r\n",
      ctid(),
      iter->first,
      iter->second->m_allpool->size(),
      iter->second->m_idle->size());
     //计算总的分配的内存大小
     total_size += (iter->second->m_allpool->size() * iter->first) / 1024.0;
    }
    c_znLog::_msg("线程ID=%8u, 分配内存总量 = %.4f MB\r\n", ctid(), total_size / 1024.0);
    tick->utick = time(0);
   }
   //===========================30秒输出一次内存块的实用情况================================

   //2.通过内存颗粒进行计算  如果传入参数bCalculate为false为不加入颗粒统计,只加预留字节buffer_reserved
   int allocate_size = bCalculate ? calculate_size(nSize) : (nSize + buffer_reserved);

   //3.分配内存大于内存池定义的最大颗粒而不参与内存池分配
   if (allocate_size > max_granule)
   {
    Breakpoint(NULL);
    return calloc(1, allocate_size);
   }

   
   CMemory* pResult = NULL;
   Container* pContainer = NULL;

   //4.查找当前颗粒内存对像列表
   MAP::iterator iter = pMap->find(allocate_size);
   if (iter != pMap->end())
   {
    pContainer = iter->second;
   }
   else
   {
    pContainer = new Container;
    pMap->insert(make_pair(allocate_size, pContainer));
   }

   //5.检查其他线程是否有删除情况, 有就回收到空闲内存区中
   if (!pContainer->m_allpool->empty())
   {
    pResult = pContainer->m_allpool->front();

    //调整位置
    pContainer->m_allpool->pop_front();
    pContainer->m_allpool->push_back(pResult);

    if (!pResult->IsDelete()) 
    {
     //如果正在使用
     pResult = NULL;
    }
    else
    { 
     //如果其他线程删除的内存把释放线程ID设置为0
     pResult->m_nRefThreadID = 0;
    }
   }
   
   //6.如果没有回收到内存
   if (pResult == NULL)
   {
    if (!pContainer->m_idle->empty())
    {
     //从空闲内存区中取一块内存
     pResult = pContainer->m_idle->front();
     pContainer->m_idle->pop_front();
    }
    else 
    {
     //如果还是没有可用内存则分配
     pResult = new CMemory(allocate_size);
     pContainer->m_allpool->push_back(pResult);
    }
   }

   return pResult->buffer();
  }

  static void tls_free(void* T) //回收
  {
   //1.获取要释放内存大小
   long _size = mem_size(T);

   //2.效验内存是否通过内存池分配
   long* position = (long*)&((const char*)T)[_size - buffer_reserved];

   //3.效验内存大小不是否有效
   if (*position != _size)
   {
    Breakpoint(T);
    return;
   }

   //4.指向内存对像
   ++position;
   CMemory* memory = (CMemory*)(*position);

   memory->Release();
  }

 private:
  //释放/回收
  void Release()
  {
   //如果创建的线程与加收线程同一个直接回收
   if (ctid() == m_nCrtThreadID) 
   {
    //1.获取TLS内存对像,不存在则创建
    MAP* pMap = TlsSingelton<MAP>::tlsInstance();

    if (pMap == NULL)
     return;

    MAP::iterator iter = pMap->find(m_allocate_size);
    if (iter != pMap->end())
    {
     Container* pContainer = iter->second;
     pContainer->m_idle->push_back(this);
    }
    else
    {
     Breakpoint(m_pData);
    }
   }
   else
   {
    m_nRefThreadID = ctid();
   }
  }

 public:
  bool IsDelete(void)
  {
   return m_nRefThreadID != 0 && m_nRefThreadID != m_nCrtThreadID;
  }
 public:
  unsigned char*  m_pData;
  unsigned long  m_allocate_size;
  unsigned long  m_nCrtThreadID;    //创建时线程ID
  unsigned long  m_nRefThreadID;    //删除时线程ID
 }; 

 //对象内存池
 class CMPool
 {
 public:
  void * operator new(size_t size) { return CMemory::tls_malloc(size, false); }
  void operator delete (void * p) { CMemory::tls_free(p); }
 };

 //线程实例化
 template<class T> class CTInstance
 {
 public:
  CTInstance() {}
  virtual ~CTInstance() {}

 public:
  static T* Allocate() { return TlsSingelton<T>::tlsInstance(); }
  void Release() {}
 };

}
//
//namespace new_op
//{
// inline void * operator new(size_t size)
// {
//  return BaseLib::CMemory::tls_malloc(size);
// }
//
// inline void operator delete (void * p)
// {
//  BaseLib::CMemory::tls_free(p);
// }
//
// inline void operator delete [] (void * p)
// {
//  BaseLib::CMemory::tls_free(p);
// }
//}

 

#endif //__TLS_POOLS__

 

 

采用tls_malloc 分配内存 tls_free释放内存   支持多线程

服务器内存池专用

 


 

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值