zoukankan      html  css  js  c++  java
  • 内存池技术解释

    说明:
          本文是在网上查看了相关技术课题及解说后做的一个笔记与摘录,关键在于描述这么一种思想。

    经典的内存池(Memory pool)技术是获取及释放相同大小的内存块单元对象的技术,其优点在于快速获取内存以及快速释放内存。

    经典内存池技术通常需要四个变量外部变量来管理内存单元,分别是内存块大小(总的内存块),最小内存块大小(由于指针等关系,一般要求最小内存块单元大于sizeof(void*)个字节,即4个字节),一个指向内存块首地址的指针和一个指向空闲内存块首地址的指针。具体实现结构如下:
     1class MemeoryPool
     2{
     3    private:
     4        const int m_nMemBlockSize;
     5        const int m_nItemSize;
     6    
     7    struct _FreeNode
     8    {
     9        _FreeNode *pPrev;
    10        BYTE data[m_nItemSize - sizeof(_FreeNode *) ];
    11    }
    ;
    12    struct _MemBlock
    13   {
    14        _MemBlock *pPrev;
    15        _FreeNode data[m_nMemBlockSize / m_nItemSize];
    16   }
    ;
    17    
    18       _MemBlock *m_pMemBlockHeader;
    19       _FreeNode *m_pFreeNodeHeader;
    20
    21   public:
    22       MemoryPool( int nItemSize, inte nMemBlockSize=2048)
    23          : m_nItemSize(nItemSize)
    24          , m_nMemBlockSize(nMemBlockSize)
    25          , m_pMemBlockHeader(NULL)
    26          , m_pFreeNodeHeader(NULL)
    27      {}
    28  public:
    29       void* malloc()
    30       void* free()
    31}
    ;
    32
    33void *MemoryPool::malloc()
    34{
    35   if( m_pFreeNodeHeader == NULL )   // 第一次申请内存
    36   {
    37       const int nCount = m_nMemBlockSize / m_nItemSize;
    38       _MemBlock *pMemBlock = new _MemBlock;
    39       pMemBlock->data[0].pPrev = NULL;
    40       forint i=1; i<nCount; ++i )
    41       {
    42            pMemBlock->data[i].pPrev = &pMemBlock->data[i-1];
    43       }

    44       m_pFreeNodeHeader = &pMemBlock->data[nCount-1];   // 指向内存块尾部
    45        pMemBlock->pPrev = m_pMemBlock;      // 对于第一次而言就是NULL,对于后来再次申请而言,则是前一个内存地址了!
    46       m_pMemBlock = pMemBlock; 
    47   }

    48   void *pFreeNode = m_pFreeNodeHeader;
    49   m_pFreeNodeHeader = m_pFreeNodeHeader->pPrev;
    50   return pFreeNode;
    51}

    52
    53void *MemoryPool::free()  // 将最后一块内存释放到空闲内存块区域中去
    54{
    55    
    56  }

    此处实现的内存池技术采用的是定长的最小块单元,是一个功能比较简单的内存块实现单元。

    性能分析:
           此处获取内存,除了第一次需要调用new操作以及设置指针等操作,花费较多时间,new操作需要调用系统功能,花费时间较大,指针初始化操作也需要花费较长时间,但其后每次申请内存单元的复杂度均为O(1),析构内存单元的复杂度也为O(1),因此与直接申请内存相比,内存池技术对内存的申请以及释放均有较快的速度,并且,由于内存池一次性申请是一大块内存(否则就不能称之为池了),将减少系统中的内存碎片。当然由于内存池技术需要额外的指针来指示内存单元的使用情况,因此,内存池技术对于少量内存使用的程序其空间利用率是比较低的。A coin has two faces!

    在stl设计中,大量使用了内存池技术(采用new以及new placement技术来实现),通过allocator类封装来实现,模板技术可以方便的获取最小内存对象块的大小,设定内存单元块数目就可以知道m_nMemBlockSize的大小了,而且可以动态改变。

    上述的内存池技术中采用的是定长的内存单元块申请,对于需要大量内存单元的程序,该方式所能够提供的节省时间将减少,为了使得程序能够节省更多时间,采用具有动态申请内存(从系统中)的方法,即第一次申请1KB,第二次申请2KB,第三次申请4KB,第四次申请8KB,在需要大内存单元的时候,程序依然可以节省大量大量时间。由于该方法在计算机中广泛使用,便有了一个名字:预测模型。stl中vector便是采用预测模型来实现的。

  • 相关阅读:
    快速幂精讲+代码实现
    基数排序
    Java学习-常见排序算法
    C++中不清楚的函数用法汇总
    C++中的堆及常见题目汇总
    django+nginx+uwsgi+vue部署服务器
    nginx+WSGI+uwisgi+uWISI详解及nginx/uwisgi/django交互流程
    C++中的哈希表及常见题目汇总
    C++中的二叉树及相关题目汇总
    C++中的队列及常见题目汇总
  • 原文地址:https://www.cnblogs.com/ubunoon/p/MemoryPool.html
Copyright © 2011-2022 走看看