乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      內(nèi)存池技術(shù)

       JohnnyChan 2009-07-17

      解決方案:你自己的內(nèi)存池一個(gè)(可能的)解決方法是內(nèi)存池(Memory Pool)。

          在啟動(dòng)的時(shí)候,一個(gè)內(nèi)存池Memory Pool)分配一塊很大的內(nèi)存,并將會(huì)將這個(gè)大塊(block)分成較小的塊(smaller chunks)。每次你從內(nèi)存池申請(qǐng)內(nèi)存空間時(shí),它會(huì)從先前已經(jīng)分配的塊(chunks)中得到,而不是從操作系統(tǒng)。最大的優(yōu)勢(shì)在于:

          1:非常少(幾沒有) 堆碎片

          2: 比通常的內(nèi)存申請(qǐng)/釋放(比如通過malloc, new等)的方式快另外,你可以得到以下好處:1:檢查任何一個(gè)指針是否在內(nèi)存池里2:寫一個(gè)堆轉(zhuǎn)儲(chǔ)(Heap-Dump到你的硬盤(對(duì)事后的調(diào)試非常有用)

          3: 某種內(nèi)存泄漏檢測(cè)(memory-leak detection:當(dāng)你沒有釋放所有以前分配的內(nèi)存時(shí),內(nèi)存池(Memory Pool)會(huì)拋出一個(gè)斷言(assertion)。
       

      SMemoryChunk.h

      #ifndef __SMEMORYCHUNK_H__
      #define __SMEMORYCHUNK_H__

      typedef unsigned 
      char TByte ;

      struct SMemoryChunk
      {
        TByte *Data;                
      //數(shù)據(jù) 
        std::size_t DataSize;        //該內(nèi)存塊的總大小
        std::size_t UsedSize;        //實(shí)際使用的大小
        bool IsAllocationChunk;    
        SMemoryChunk *Next;        
      //指向鏈表中下一個(gè)塊的指針。
      };

      #endif

         

      IMemoryBlock.h

      #ifndef __IMEMORYBLOCK_H__
      #define __IMEMORYBLOCK_H__

      class IMemoryBlock
      {
        
      public :
          
      virtual~IMemoryBlock() {};

          
      virtual void *GetMemory(const std::size_t &sMemorySize) = 0;
          
      virtual void FreeMemory(void *ptrMemoryBlock, const std::size_t &sMemoryBlockSize) = 0; 

      };

      #endif

         

      CMemoryPool.h

      #ifndef __CMEMORYPOOL_H__
      #define __CMEMORYPOOL_H__


      #include "IMemoryBlock.h"
      #include "SMemoryChunk.h"


      staticconst std::size_t DEFAULT_MEMORY_POOL_SIZE        = 1000;//初始內(nèi)存池的大小
      static const std::size_t DEFAULT_MEMORY_CHUNK_SIZE       = 128;//Chunk的大小
      static const std::size_t DEFAULT_MEMORY_SIZE_TO_ALLOCATE = DEFAULT_MEMORY_CHUNK_SIZE * 2;

      class CMemoryPool : public IMemoryBlock
      {
      public:
          CMemoryPool(
      const std::size_t &sInitialMemoryPoolSize = DEFAULT_MEMORY_POOL_SIZE, 
                      
      const std::size_t &sMemoryChunkSize = DEFAULT_MEMORY_CHUNK_SIZE,
                      
      const std::size_t &sMinimalMemorySizeToAllocate = DEFAULT_MEMORY_SIZE_TO_ALLOCATE,
                      
      bool bSetMemoryData = false
                      );


          
      virtual ~CMemoryPool();

          
      //從內(nèi)存池中申請(qǐng)內(nèi)存
          virtual void* GetMemory(const std::size_t &sMemorySize);
          
      virtual void  FreeMemory(void *ptrMemoryBlock, const std::size_t &sMemoryBlockSize);
          
      private:
          
      //申請(qǐng)內(nèi)存OS
          bool AllocateMemory(const std::size_t &sMemorySize);
          
      void FreeAllAllocatedMemory();
          
          
      //計(jì)算可以分多少塊
          unsigned int CalculateNeededChunks(const std::size_t &sMemorySize);

          
      //計(jì)算內(nèi)存池最合適的大小
          std::size_t CMemoryPool::CalculateBestMemoryBlockSize(const std::size_t &sRequestedMemoryBlockSize);
          
          
      //建立鏈表.每個(gè)結(jié)點(diǎn)Data指針指向內(nèi)存池中的內(nèi)存地址
          bool LinkChunksToData(SMemoryChunk* ptrNewChunks, unsigned int uiChunkCount, TByte* ptrNewMemBlock);
          
          
      //重新計(jì)算塊(Chunk)的大小1024--896--768--640--512------------
          bool RecalcChunkMemorySize(SMemoryChunk* ptrChunk, unsigned int uiChunkCount);
          
          SMemoryChunk* SetChunkDefaults(SMemoryChunk *ptrChunk);
          

          
      //搜索鏈表找到一個(gè)能夠持有被申請(qǐng)大小的內(nèi)存塊(Chunk).如果它返回NULL,那么在內(nèi)存池中沒有可用的內(nèi)存
          SMemoryChunk* FindChunkSuitableToHoldMemory(const std::size_t &sMemorySize);

          std::size_t MaxValue(
      const std::size_t &sValueA, const std::size_t &sValueB) const;
          
          
      void SetMemoryChunkValues(SMemoryChunk *ptrChunk, const std::size_t &sMemBlockSize);

          SMemoryChunk* SkipChunks(SMemoryChunk *ptrStartChunk, unsigned 
      int uiChunksToSkip);

      private:

          SMemoryChunk *m_ptrFirstChunk;
          SMemoryChunk *m_ptrLastChunk;   
          SMemoryChunk *m_ptrCursorChunk;

          std::size_t m_sTotalMemoryPoolSize;  
      //內(nèi)存池的總大小
          std::size_t m_sUsedMemoryPoolSize;   //以使用內(nèi)存的大小
          std::size_t m_sFreeMemoryPoolSize;   //可用內(nèi)存的大小

          std::size_t m_sMemoryChunkSize;     
      //(Chunk)的大小
          unsigned int m_uiMemoryChunkCount;  //(Chunk)的數(shù)量
          unsigned int m_uiObjectCount;

          
      bool m_bSetMemoryData ; 
          std::size_t m_sMinimalMemorySizeToAllocate;


      };

      #endif

       



      CMemoryPool.cpp

      #include "stdafx.h"
      #include "CMemorypool.h"

      #include <math.h>
      #include <assert.h>

      static const int NEW_ALLOCATED_MEMORY_CONTENT = 0xFF ;


      CMemoryPool::CMemoryPool(
      const std::size_t &sInitialMemoryPoolSize,
                               
      const std::size_t &sMemoryChunkSize,
                               
      const std::size_t &sMinimalMemorySizeToAllocate,
                               
      bool bSetMemoryData)
      {
          m_ptrFirstChunk  = NULL;
          m_ptrLastChunk   = NULL;
          m_ptrCursorChunk = NULL;

          m_sTotalMemoryPoolSize = 0;
          m_sUsedMemoryPoolSize  = 0;
          m_sFreeMemoryPoolSize  = 0;

          m_sMemoryChunkSize   = sMemoryChunkSize;
          m_uiMemoryChunkCount = 0;
          m_uiObjectCount      = 0;

          m_bSetMemoryData               = !bSetMemoryData;
          m_sMinimalMemorySizeToAllocate = sMinimalMemorySizeToAllocate;

          AllocateMemory(sInitialMemoryPoolSize);
      }

      CMemoryPool::~CMemoryPool()
      {

      }

      void* CMemoryPool::GetMemory(const std::size_t &sMemorySize)
      {
          std::size_t sBestMemBlockSize = CalculateBestMemoryBlockSize(sMemorySize);  
          SMemoryChunk* ptrChunk = NULL;
          
      while(!ptrChunk)
          {

              ptrChunk = FindChunkSuitableToHoldMemory(sBestMemBlockSize);

              
      //ptrChunk等于NULL表示內(nèi)存池內(nèi)存不夠用
              if(!ptrChunk)
              {
                  sBestMemBlockSize = MaxValue(sBestMemBlockSize, CalculateBestMemoryBlockSize(m_sMinimalMemorySizeToAllocate));
                  
      //OS申請(qǐng)更多的內(nèi)存
                  AllocateMemory(sBestMemBlockSize);
              }
          }
          
      //下面是找到可用的塊(Chunk)代碼
          m_sUsedMemoryPoolSize += sBestMemBlockSize;
          m_sFreeMemoryPoolSize -= sBestMemBlockSize;
          m_uiObjectCount++;
          
      //標(biāo)記該塊(Chunk)已用
          SetMemoryChunkValues(ptrChunk, sBestMemBlockSize);

          
      return ((void *) ptrChunk->Data);
      }

      void CMemoryPool::FreeMemory(void *ptrMemoryBlock, const std::size_t &sMemoryBlockSize)
      {





      }

      bool CMemoryPool::AllocateMemory(const std::size_t &sMemorySize)
      {
          
      //計(jì)算可以分多少塊(1000 / 128 = 8)
          unsigned int uiNeededChunks = CalculateNeededChunks(sMemorySize);

          
      //當(dāng)內(nèi)存池的初始大小為1000字節(jié),塊(Chunk)大小128字節(jié),分8塊還差24字節(jié).怎么辦?
          //
      解決方案:多申請(qǐng)24字節(jié)
          std::size_t sBestMemBlockSize = CalculateBestMemoryBlockSize(sMemorySize);

          
      //OS申請(qǐng)內(nèi)存
          TByte *ptrNewMemBlock = (TByte*) malloc(sBestMemBlockSize);

          
      //分配一個(gè)結(jié)構(gòu)體SmemoryChunk的數(shù)組來(lái)管理內(nèi)存塊
          SMemoryChunk *ptrNewChunks = (SMemoryChunk*) malloc((uiNeededChunks * sizeof(SMemoryChunk))); 


          m_sTotalMemoryPoolSize += sBestMemBlockSize;
          m_sFreeMemoryPoolSize += sBestMemBlockSize;
          m_uiMemoryChunkCount += uiNeededChunks;


          
      if(m_bSetMemoryData)
          {
              memset(((
      void *) ptrNewMemBlock), NEW_ALLOCATED_MEMORY_CONTENT, sBestMemBlockSize);
          }

          
      return LinkChunksToData(ptrNewChunks, uiNeededChunks, ptrNewMemBlock);

      }

      unsigned 
      int CMemoryPool::CalculateNeededChunks(const std::size_t &sMemorySize)
      {
          
      float f = (float) (((float)sMemorySize) / ((float)m_sMemoryChunkSize));
          
      return ((unsigned int) ceil(f));
      }

      std::size_t CMemoryPool::CalculateBestMemoryBlockSize(
      const std::size_t &sRequestedMemoryBlockSize)
      {
          unsigned 
      int uiNeededChunks = CalculateNeededChunks(sRequestedMemoryBlockSize);
          
      return std::size_t((uiNeededChunks * m_sMemoryChunkSize));
      }

      bool CMemoryPool::LinkChunksToData(SMemoryChunk* ptrNewChunks, unsigned int uiChunkCount, TByte* ptrNewMemBlock)
      {

          SMemoryChunk *ptrNewChunk = NULL;
          unsigned 
      int uiMemOffSet = 0; 
          
      bool bAllocationChunkAssigned = false ;
          
      for(unsigned int i = 0; i < uiChunkCount; i++)
          {    
              
      //建立鏈表
              if(!m_ptrFirstChunk)
              {
                  m_ptrFirstChunk = SetChunkDefaults(&(ptrNewChunks[0]));
                  m_ptrLastChunk = m_ptrFirstChunk;
                  m_ptrCursorChunk = m_ptrFirstChunk;
              }
              
      else
              {
                  ptrNewChunk = SetChunkDefaults(&(ptrNewChunks[i]));
                  m_ptrLastChunk->Next = ptrNewChunk;
                  m_ptrLastChunk = ptrNewChunk;
              }
              
      //根據(jù)塊(Chunk)的大小計(jì)算下一塊的內(nèi)存偏移地址
              uiMemOffSet = (i * ((unsigned int) m_sMemoryChunkSize));

              
      //結(jié)點(diǎn)指向內(nèi)存偏移地址
              m_ptrLastChunk->Data = &(ptrNewMemBlock[uiMemOffSet]);


              
      if(!bAllocationChunkAssigned)
              {
                  m_ptrLastChunk->IsAllocationChunk = 
      true;
                  bAllocationChunkAssigned = 
      true;
              }
          }


          
      return RecalcChunkMemorySize(m_ptrFirstChunk, m_uiMemoryChunkCount);

      }


      bool CMemoryPool::RecalcChunkMemorySize(SMemoryChunk *ptrChunk, unsigned int uiChunkCount)
      {
          unsigned 
      int uiMemOffSet = 0 ;
          
      for(unsigned int i = 0; i < uiChunkCount; i++)
          {
              
      if(ptrChunk)
              {
                  uiMemOffSet = (i * ((unsigned 
      int) m_sMemoryChunkSize)) ;
                  ptrChunk->DataSize = (((unsigned 
      int) m_sTotalMemoryPoolSize) - uiMemOffSet);
                  ptrChunk = ptrChunk->Next ;
              }
              
      else
              {
                  assert(
      false && "Error : ptrChunk == NULL");
                  
      return false;
              }
          }
          
      return true;
      }

      SMemoryChunk* CMemoryPool::SetChunkDefaults(SMemoryChunk* ptrChunk)
      {
          
      if(ptrChunk)
          {
              ptrChunk->Data = NULL;
              ptrChunk->DataSize = 0;
              ptrChunk->UsedSize = 0;
              ptrChunk->IsAllocationChunk = 
      false;
              ptrChunk->Next = NULL;
          }
          
      return ptrChunk;
      }


      SMemoryChunk *CMemoryPool::FindChunkSuitableToHoldMemory(
      const std::size_t &sMemorySize)
      {
          unsigned 
      int uiChunksToSkip = 0;
          
      bool bContinueSearch = true;
          SMemoryChunk *ptrChunk = m_ptrCursorChunk; 
          
      for(unsigned int i = 0; i < m_uiMemoryChunkCount; i++)
          {
              
      if(ptrChunk)
              {
                  
      if(ptrChunk == m_ptrLastChunk) 
                  {
                      ptrChunk = m_ptrFirstChunk;
                  }

                  
      if(ptrChunk->DataSize >= sMemorySize)
                  {
                      
      if(ptrChunk->UsedSize == 0)
                      {
                          m_ptrCursorChunk = ptrChunk;
                          
      return ptrChunk;
                      }
                  }
                  uiChunksToSkip = CalculateNeededChunks(ptrChunk->UsedSize);
                  
      if(uiChunksToSkip == 0) uiChunksToSkip = 1;
                  ptrChunk = SkipChunks(ptrChunk, uiChunksToSkip);
              }
              
      else
              {
                  bContinueSearch = 
      false 
              }
          }
          
      return NULL;
      }

      std::size_t CMemoryPool::MaxValue(
      const std::size_t &sValueA, const std::size_t &sValueB) const
      {
          
      if(sValueA > sValueB)
          {
              
      return sValueA;
          }
          
      return sValueB;
      }

      void CMemoryPool::SetMemoryChunkValues(SMemoryChunk *ptrChunk, const std::size_t &sMemBlockSize)
      {
          
      if((ptrChunk))
          {
              ptrChunk->UsedSize = sMemBlockSize;
          }
          
      else
          {
              assert(
      false && "Error : Invalid NULL-Pointer passed");
          }
      }

      SMemoryChunk *CMemoryPool::SkipChunks(SMemoryChunk *ptrStartChunk, unsigned 
      int uiChunksToSkip)
      {
          SMemoryChunk *ptrCurrentChunk = ptrStartChunk;
          
      for(unsigned int i = 0; i < uiChunksToSkip; i++)
          {
              
      if(ptrCurrentChunk)
              {
                  ptrCurrentChunk = ptrCurrentChunk->Next;
              }
              
      else
              {

                  assert(
      false && "Error : Chunk == NULL was not expected.");
                  
      break ;
              }
          }
          
      return ptrCurrentChunk;
      }

         


      測(cè)試
      方法:

      // 111.cpp : 定義控制臺(tái)應(yīng)用程序的入口點(diǎn)。
      //

      #include "stdafx.h"
      #include "CMemoryPool.h"
      CMemoryPool* g_pMemPool = NULL;
      class testMemoryPool
      {
      public:
          testMemoryPool(){
          }

          
      void *operator new(std::size_t ObjectSize)
          {
              
      return g_pMemPool->GetMemory(ObjectSize) ;
          }

      private:
          
      char a[25];
          
      bool b;
          
      long c;
      };
      //sizeof(32);


      int _tmain(int argc, _TCHAR* argv[])
      {

          g_pMemPool = 
      new CMemoryPool();


          testMemoryPool* test = 
      new testMemoryPool();




          
      return 0;
      }

       

        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶 評(píng)論公約

        類似文章 更多