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

  • 相关阅读:
    python发送邮件
    nginx的信号量和平滑升级
    CentOS6下nginx的源码安装
    mysql备份与还原之mysqldump
    myslq基本语法(3)
    mysql基本语法(2)
    MySQL中数据表和数据的操作
    mysql概述及基本语法(1)
    shell的随机数
    浏览器的跨域问题的解决办法
  • 原文地址:https://www.cnblogs.com/IS2120/p/6746034.html
Copyright © 2011-2022 走看看