栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C++实现简单内存池

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C++实现简单内存池

内存池是什么?

内存池(Memory Pool)是一种内存分配方式,又被称为固定大小区块规划(fixed-size-blocks allocation)。通常我们习惯直接使用new、malloc等API申请分配内存,这样做的缺点在于:由于所申请内存块的大小不定,当频繁使用时会造成大量的内存碎片并进而降低性能。

内存池如何实现? 1.内存结构
typedef struct {
  struct list_head list;
  int fd;  // Unix系映射文件句柄
  int tid;
} Heap;

typedef struct {
  unsigned int unMem_flg; // 块标志
  unsigned int unMem_size; // 块大小
} Heapinf;

#define ALLOCATE_MEM_ALL_BLOCK 0xFFFFFFFF //不可分区的块
#define ALLOCATE_MEM_SEP_BLOCK 0x11111111 //可分区的块
#define ALLOCATE_MEM_STATUS_USED 0x22222222 //已使用的块
#define ALLOCATE_MEM_STATUS_FREE 0x33333333 //未使用的块

2.接口
class HeapManage {
 public:
  // 从内存池分配指定内存
  static void *_allocate(unsigned int size, unsigned int tid);
  // 将内存返回内存池
  static int _release(void *ptr);
  
 private:
  struct list_head head;
  HeapManage();
  virtual ~HeapManage(){};
  // 获取堆内存/虚拟内存
  static void *_allocate_p(int mode, unsigned int unMemSize, int mapfd);
  // 释放堆内存/虚拟内存
  static void _release_p(list_head *head);
  // 单例模式
  static HeapManage &getInstance(); 
  static HeapManage *sInstance;
  class HeapFree {
   public:
    HeapFree() {}
    virtual ~HeapFree();
  };
  friend class HeapManage::HeapFree;
  static HeapFree mHeapFree;
};

#define allocate(size) HeapManage::_allocate(size, 0)
#define release(ptr) HeapManage::_release(ptr)
3.分配
void *HeapManage::_allocate(unsigned int ulAreaSize, unsigned int tid) {
  void *pReturn_code = NULL;
  ......

  unMemAct_size = length_align(ulAreaSize);
  head = &getInstance().head;
  pHeap = list_entry(head->next, Heap, list);
  iMem_fd = pHeap->fd;

  if (unMemAct_size > 64 * 1024) {
    pHeap = (Heap *)_allocate_p(
        0, unMemAct_size + sizeof(Heap) + sizeof(Heapinf) * 2, iMem_fd);
    if (pHeap != NULL) {
      list_add_tail(&pHeap->list, head);
      pHeap->tid = tid;
      pReturn_code = (char *)pHeap + sizeof(Heap) + sizeof(Heapinf);
    } else {
      ;
    }
    goto EXIT;
  }

  pWorkInf = (Heapinf *)((char *)pHeap + sizeof(Heap) + sizeof(Heapinf));
  do {
    pHeapInf = (Heapinf *)((char *)pHeap + sizeof(Heap));
    if (pHeapInf->unMem_flg == ALLOCATE_MEM_ALL_BLOCK) {
      if (pHeap->list.next != head) {
        pHeap = list_entry(pHeap->list.next, Heap, list);
        pWorkInf = (Heapinf *)((char *)pHeap + sizeof(Heap) + sizeof(Heapinf));
      } else {
        pHeap = (Heap *)_allocate_p(1, 0, iMem_fd);
        if (pHeap != NULL) {
          list_add_tail(&pHeap->list, head);
          pWorkInf =
              (Heapinf *)((char *)pHeap + sizeof(Heap) + sizeof(Heapinf));
        } else {
          ;
        }
      }
    } else if (pHeap->tid != tid) {
      if (pHeap->list.next != head) {
        ... ...
      } else {
        ... ...
      }
    } else if (pWorkInf->unMem_flg == ALLOCATE_MEM_STATUS_FREE) {
      if (pWorkInf->unMem_size >= unMemAct_size + sizeof(Heapinf) * 2) {
        
        
        ......
        iMem_flg = 1;
        ...... 
      } else {
        pWorkInf = (Heapinf *)((char *)pWorkInf + sizeof(Heapinf) * 2 +
                               pWorkInf->unMem_size);
      }
    } else if (pWorkInf->unMem_flg == ALLOCATE_MEM_STATUS_USED) {
      pWorkInf = (Heapinf *)((char *)pWorkInf + sizeof(Heapinf) * 2 +
                             pWorkInf->unMem_size);
    } else if (pWorkInf->unMem_flg == ALLOCATE_MEM_SEP_BLOCK) {
      if (pHeap->list.next != head) {
        pHeap = list_entry(pHeap->list.next, Heap, list);
        pWorkInf = (Heapinf *)((char *)pHeap + sizeof(Heap) + sizeof(Heapinf));
      } else {
        ... ...
      }
    } else {
      goto EXIT;
    }
  } while (iMem_flg != 1);

EXIT:
  return pReturn_code;
}
4.释放
int HeapManage::_release(void *ptr) {
  int iReturn_code;
  ......

  iReturn_code = 0;
  if (ptr == 0) goto EXIT;

  head = &getInstance().head;

  inf = (Heapinf *)((char *)ptr - sizeof(Heapinf));
  switch (inf->unMem_flg) {
    case ALLOCATE_MEM_STATUS_USED:
      pwk_inf = inf;
      do {
        pwk_inf = (Heapinf *)((char *)pwk_inf + pwk_inf->unMem_size +
                              sizeof(Heapinf) * 2);
        if (pwk_inf->unMem_flg != ALLOCATE_MEM_STATUS_FREE &&
            pwk_inf->unMem_flg != ALLOCATE_MEM_STATUS_USED &&
            pwk_inf->unMem_flg != ALLOCATE_MEM_SEP_BLOCK) {
          iReturn_code = -1;
          goto EXIT;
        }
      } while (pwk_inf->unMem_flg != ALLOCATE_MEM_SEP_BLOCK);

      pHeap = (Heap *)((char *)pwk_inf -
                       (sizeof(Heap) + sizeof(Heapinf) + pwk_inf->unMem_size));

      unMemFree_size = inf->unMem_size;

      pwk_inf = (Heapinf *)((char *)inf + inf->unMem_size + sizeof(Heapinf));
      if (pwk_inf->unMem_flg != ALLOCATE_MEM_STATUS_USED ||
          pwk_inf->unMem_size != unMemFree_size) {
        iReturn_code = -1;
        goto EXIT;
      }

      unMemNext_free_flg = 0;
      pwk_inf = (Heapinf *)((char *)pwk_inf + sizeof(Heapinf));
      // 根据释放区域前后区域是否需要合并,重新计算空闲区大小
      ... ...
      ... ...
      
      if (pHeap->list.prev == pHeap->list.next) {
        goto EXIT;
      } else {
        inf = (Heapinf *)((char *)pHeap + sizeof(Heap));
        if (inf->unMem_size == (inf + 1)->unMem_size + sizeof(Heapinf) * 2) {
          ;
        } else {
          goto EXIT;
        }
      }
      break;
    case ALLOCATE_MEM_ALL_BLOCK:
      pHeap = (Heap *)((char *)inf - sizeof(Heap));
      break;
    default:
      iReturn_code = -1;
      goto EXIT;
  }
  
  // 释放空内存池
  unMemFree_size = ((Heapinf *)(pHeap + 1))->unMem_size;
  unMemFree_size += sizeof(Heap) + sizeof(Heapinf) * 2;
  list_del(&pHeap->list);
#if defined(WIN32)
  hGlobal = GlobalHandle(pHeap);
  GlobalUnlock(hGlobal);
  GlobalFree(hGlobal);
#else
  munmap(pHeap, unMemFree_size);
#endif
EXIT:
  return iReturn_code;
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/630589.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号