概述
动态内存池是一种内存管理技术,主要用于提高程序在频繁进行小块内存分配和释放时的效率。相比于传统的malloc/free、new/delete、或其他动态内存分配函数,内存池预先申请一大块连续内存,并将这块大内存分割成多个固定大小或一定范围大小的小内存块,然后以池的方式管理和分发这些小内存块。
内存池一般包括:初始化、分配内存块、回收内存块以及整体释放等功能模块。具体实现时,可以通过数组、链表或树等多种数据结构来组织和追踪空闲内存块的状态。当请求分配内存时,从池中取出一个空闲块。当内存不再使用时,将其归还到内存池中,以便后续复用。
CHP_DynamicMemPool类
在C++中,并没有内置的内存池类。为了方便应用层使用内存池,我们封装了CHP_DynamicMemPool类。CHP_DynamicMemPool类是对动态内存池的封装,适用于需要频繁使用内存块,内存块的总数相对固定,但每个内存块的大小不一样的场景,一般会结合队列使用。CHP_DynamicMemPool类的头文件,可参考下面的示例代码。
#pragma once #include <list> #include "HP_Mutex.h" class CHP_DynamicMemPool { public: CHP_DynamicMemPool(); ~CHP_DynamicMemPool(); void Init(unsigned int uiMaxBlockCount, bool bNeedLock = true); char *Alloc(unsigned int uiBytes); void Release(char *pBuf); void Reset(); unsigned int GetTotalBlockCount(); void GetCurBlockCount(unsigned int &uiUsedCount, unsigned int &uiFreeCount); private: typedef struct _TDynamicMemBlock { char *pBlock; unsigned int uiBlockLen; }TDynamicMemBlock; typedef std::list<TDynamicMemBlock> TDynamicMemBlockList; unsigned int m_uiMaxBlockCount; bool m_bNeedLock; TDynamicMemBlockList m_listUsed; TDynamicMemBlockList m_listFree; CHP_Mutex m_mutexBlockList; };
CHP_DynamicMemPool类有6个公共成员函数,下面逐一进行介绍。
Init:初始化内存池,内存池中含有多个内存块,每个内存块的大小可能不一样。参数uiMaxBlockCount为内存块的最大个数,分配内存时,如果超过内存块的最大个数,则分配失败;参数bNeedLock表示是否需要加锁,默认值为true,如果应用层使用CHP_DynamicMemPool对象时已经加了锁,这里可以传入false。
Alloc:分配指定大小的buffer。内存池中含有一个已使用队列和一个空闲队列,分配buffer时,先从空闲队列中查找是否有符合条件的内存块。如果有,直接返回该内存块;如果没有,则检查所有内存块的数量是否超过内存块的最大个数。如果没有超过,则新建一个合适大小的内存块,并加入已使用队列中。如果超过,且空闲队列非空,则从空闲队列取一个内存块,并重新分配合适大小的内存。参数uiBytes为buffer的大小,单位为字节。返回非NULL表示成功,否则失败。
Release:释放buffer,将其从已使用队列放入到空闲队列中。参数pBuf为之前分配的的buffer指针。
Reset:重置内存池,会释放所有内存块中的内存。
GetTotalBlockCount:获取所有内存块的数量。
GetCurBlockCount:获取已使用内存块和空闲内存块的数量。参数uiUsedCount为已使用内存块的数量,参数uiFreeCount为空闲内存块的数量。