zoukankan      html  css  js  c++  java
  • 一个分配固定大小块的内存池(memory pool) 的例子 FROM POCO

    //
    // MemoryPool.h
    //
    // $Id: //poco/1.4/Foundation/include/Poco/MemoryPool.h#1 $
    //
    // Library: Foundation
    // Package: Core
    // Module:  MemoryPool
    //
    // Definition of the MemoryPool class.
    //
    // Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
    // and Contributors.
    //

    /*
    //z 2011-06-23 15:13:07@is2120.CSDN 转载请注明出处
    设计思想:
    比较简单,申请若干个(128)固定大小的内存块,
    将各内存块指针存放在vector中,申请则出vector,释放则回收到vec中去。
    */

    #ifndef Foundation_MemoryPool_INCLUDED
    #define Foundation_MemoryPool_INCLUDED


    #include  "Poco/Foundation.h"
    #include  "Poco/Mutex.h"
    #include  <vector>
    #include  <cstddef>


    namespace  Poco {

    /*
    14:01 2011-6-23
    一个固定大小内存块的pool
    这个class的主要目的是加速内存分配
    同时在相同大小的块一遍又一遍分配时避免了内存碎片
    */

    class  Foundation_API MemoryPool
      /// A simple pool for fixed-size memory blocks.
      ///
      /// The main purpose of this class is to speed-up
      /// memory allocations, as well as to reduce memory
      /// fragmentation in situations where the same blocks
      /// are allocated all over again, such as in server
      /// applications.
      ///
      /// All allocated blocks are retained for future use.
      /// A limit on the number of blocks can be specified.
      /// Blocks can be preallocated.
    {
    public :
      MemoryPool(std::size_t  blockSize, int  preAlloc = 0int  maxAlloc = 0 );
        //z@is2120 14:03 2011-6-23
        //z 使用给定的blocksize创建一个memorypool。
        //z 预分配的大小由preAlloc指定
        /// Creates a MemoryPool for blocks with the given blockSize.
        /// The number of blocks given in preAlloc are preallocated.
        
      ~MemoryPool();

      //z 从memory pool中得到一个block
      void * get();
        /// Returns a memory block. If there are no more blocks
        /// in the pool, a new block will be allocated.
        ///
        /// If maxAlloc blocks are already allocated, an
        /// OutOfMemoryException is thrown.

      //z 将一个 memory block 返回到pool中去。
      void  release(void * ptr);
        /// Releases a memory block and returns it to the pool.

      //z 返回 block size
      std::size_t  blockSize() const ;
        /// Returns the block size.
      
      //z 返回已分配的 blocks 的数目
      int  allocated() const ;
        /// Returns the number of allocated blocks.
        
      //z 返回在pool中可用的块数目
      int  available() const ;
        /// Returns the number of available blocks in the pool.

    private :
      //z 禁用了默认构造函数;拷贝构造函数以及赋值构造函数
      MemoryPool();
      MemoryPool(const  MemoryPool&);
      MemoryPool& operator  = (const  MemoryPool&);
      
      //z 保留128的block
      enum
      {
        BLOCK_RESERVE = 128
      };
      
      //z 使用了vector来保存block的地址
      typedef  std::vector<char *> BlockVec;
      
      //z 块大小
      std::size_t  _blockSize;
      //z 允许的最大块数目
      int          _maxAlloc;
      //z 已分配
      int          _allocated;
      //z 存储块地址的容器
      BlockVec    _blocks;
      //z 互斥
      FastMutex   _mutex;
    };


    //
    // inlines
    //
    //z 返回块大小
    inline  std::size_t  MemoryPool::blockSize() const
    {
      return  _blockSize;
    }

    //z 返回总的分配的数目
    inline  int  MemoryPool::allocated() const
    {
      return  _allocated;
    }

    //z 凡存在blocks中的都是未交付使用的(但已分配)
    inline  int  MemoryPool::available() const
    {
      return  (int ) _blocks.size();
    }


    // namespace Poco


    #endif  // Foundation_MemoryPool_INCLUDED

    #include  "Poco/MemoryPool.h"
    #include  "Poco/Exception.h"

    namespace  Poco {


    MemoryPool::MemoryPool(std::size_t  blockSize, int  preAlloc, int  maxAlloc):
      _blockSize(blockSize),
      _maxAlloc(maxAlloc),
      _allocated(preAlloc)
    {
      poco_assert (maxAlloc == 0  || maxAlloc >= preAlloc);
      poco_assert (preAlloc >= 0  && maxAlloc >= 0 );

      int  r = BLOCK_RESERVE;
      if  (preAlloc > r)
        r = preAlloc;
      if  (maxAlloc > 0  && maxAlloc < r)
        r = maxAlloc;
      
      //z vector 保留r空间
      _blocks.reserve(r);
      
      for  (int  i = 0 ; i < preAlloc; ++i)
      {
        //z 直接分配;此时会不会出现异常?
        _blocks.push_back(new  char [_blockSize]);
      }
    }

    MemoryPool::~MemoryPool()
    {
      //z 所有的都放在blockvec中
      for  (BlockVec::iterator it = _blocks.begin(); it != _blocks.end(); ++it)
      {
        delete  [] *it;
      }
    }


    void * MemoryPool::get()
    {
      FastMutex::ScopedLock lock(_mutex);
      
      if  (_blocks.empty())
      {
        if  (_maxAlloc == 0  || _allocated < _maxAlloc)
        {
          ++_allocated;
          return  new  char [_blockSize];
        }
        else  throw  OutOfMemoryException("MemoryPool exhausted" );
      }
      else
      {
        //z 从尾端取出一个
        char * ptr = _blocks.back();
        //z 从尾端弹出
        _blocks.pop_back();
        return  ptr;
      }
    }

      
    void  MemoryPool::release(void * ptr)
    {
      FastMutex::ScopedLock lock(_mutex);
      
      //z 将get的内存还回vec中去。
      _blocks.push_back(reinterpret_cast <char *>(ptr));
    }


    // namespace Poco

  • 相关阅读:
    java+opencv实现图像灰度化
    java实现高斯平滑
    hdu 3415 单调队列
    POJ 3368 Frequent values 线段树区间合并
    UVA 11795 Mega Man's Mission 状态DP
    UVA 11552 Fewest Flops DP
    UVA 10534 Wavio Sequence DP LIS
    UVA 1424 uvalive 4256 Salesmen 简单DP
    UVA 1099 uvalive 4794 Sharing Chocolate 状态DP
    UVA 1169uvalive 3983 Robotruck 单调队列优化DP
  • 原文地址:https://www.cnblogs.com/IS2120/p/6746034.html
Copyright © 2011-2022 走看看