#ifndef __MEMORYPOOL__H__
#define __MEMORYPOOL__H__
#include <mutex>
#define MemCount 13
//#define UseMulThread
enum MemorySize
{
Mem4 = 0,
Mem8 = 1,
Mem16 = 2,
Mem32 = 3,
Mem64 = 4,
Mem128 = 5,
Mem256 = 6,
Mem512 = 7,
Mem1024 = 8,
Mem2048 = 9,
Mem4096 = 10,
Mem8192 = 11,
MemBig = 12
};
struct MemoryNode
{
MemoryNode(){
memset(this, 0, sizeof(*this));
}
char *data;
MemoryNode *next;
};
struct MemoryData
{
MemoryData(){
memset(this, 0, sizeof(*this));
}
int nCount;
int nUnit;
MemoryNode *use;
MemoryNode *free;
MemoryNode *freeLast;
MemoryData *next;
char *data;
};
class MemoryPool
{
public:
MemoryPool();
~MemoryPool();
bool Init();
int GetMemSize(int num);
int GetMemKey(int nSize);
void *GetMem(int nSize);
MemoryData * CreateMeo(int nKey);
MemoryData * CreateBigMeo(int nSize);
bool FreeMeo(void *address, int nSize = 0);
bool FreeOnKey(void *address, int nKey);
void DestoryMeo();
public:
#ifdef UseMulThread
std::mutex m_DataMutex;
#endif
MemoryData m_Data[MemCount];
int m_nCount; //单个模块小块数量
};
extern MemoryPool *g_Memory;
#endif
#include "MemoryPool.h"
MemoryPool *g_Memory = nullptr;
MemoryPool::MemoryPool()
{
}
MemoryPool::~MemoryPool()
{
DestoryMeo();
}
int MemoryPool::GetMemSize(int num)
{
switch (num)
{
case Mem4: return 4;
case Mem8: return 8;
case Mem16: return 16;
case Mem32:return 32;
case Mem64:return 64;
case Mem128:return 128;
case Mem256:return 256;
case Mem512:return 512;
case Mem1024:return 1024;
case Mem2048:return 2048;
case Mem4096:return 4096;
case Mem8192:return 8192;
case MemBig:return 0;
default:
return -1;
}
}
//初始化
bool MemoryPool::Init()
{
//每个块数量
m_nCount = 1000;
for (int i = 0; i < MemCount; i++)
{
if (i == MemBig)
continue;
//当前块大小
int nUnit = GetMemSize(i);
if (nUnit <= 0)
continue;
m_Data[i].nCount = m_nCount;
m_Data[i].nUnit = nUnit;
//申请内存
m_Data[i].data = new char[m_nCount * nUnit];
//申请失败 数量减半重新申请
while (m_Data[i].nCount > 0 && m_Data[i].data == nullptr)
{
m_Data[i].nCount /= 2;
m_Data[i].data = new char[m_Data[i].nCount * nUnit];
}
//每个大模块未使用小块 单独用指针连接起来
for (int j = 0; j < m_Data[i].nCount; j++)
{
MemoryNode * n = new MemoryNode;
n->data = m_Data[i].data + j * m_Data[i].nUnit;
if (m_Data[i].free == nullptr)
{
m_Data[i].free = n;
m_Data[i].freeLast = n;
}
else
{
m_Data[i].freeLast->next = n;
m_Data[i].freeLast = n;
}
}
}
return true;
}
int MemoryPool::GetMemKey(int nSize)
{
//当前大小 匹配对应的模块id
int i = Mem8192;
for (i = Mem8192; i >= 0; i--)
{
int nUnit = GetMemSize(i);
if (nSize > nUnit)
return i + 1;
}
return Mem4;
}
//申请内存
void *MemoryPool::GetMem(int nSize)
{
if (nSize <= 0) return nullptr;
#ifdef UseMulThread
m_DataMutex.lock();
#endif
//申请内存大小的对应模块id
int nKey = GetMemKey(nSize);
//std::cout << "分配大小 = " << nSize << std::endl;
//当前大模块是否还有未使用小块
MemoryData *t = &m_Data[nKey];
while (t)
{
if (t->free != nullptr)
break;
t = t->next;
}
//不是超大模块
if (nKey != MemBig)
{
//还有未使用小块
if (t)
{
//取出未使用小块
MemoryNode *n = t->free;
t->free = t->free->next;
n->next = nullptr;
//使用小块链表为空
if (t->use == nullptr)
{
t->use = n;
}
else{
//将取出小块添加到 使用链表中
MemoryNode *m = t->use;
while (m && m->next)
{
m = m->next;
}
m->next = n;
}
#ifdef UseMulThread
m_DataMutex.unlock();
#endif
return n->data;
}
else{
//没有为使用的小块了
//重新分配一个大模块
MemoryData * newdata = CreateMeo(nKey);
if (newdata == nullptr)
{
#ifdef UseMulThread
m_DataMutex.unlock();
#endif
return nullptr;
}
//添加到对应模块id中
t = &m_Data[nKey];
while (t && t->next)
{
t = t->next;
}
t->next = newdata;
t = newdata;
//从重新分配的大模块中取出为使用的小块
MemoryNode *n = t->free;
t->free = t->free->next;
n->next = nullptr;
//添加到使用链表中
if (t->use == nullptr)
{
t->use = n;
}
else{
MemoryNode *m = t->use;
while (m && m->next)
{
m = m->next;
}
m->next = n;
}
#ifdef UseMulThread
m_DataMutex.unlock();
#endif
return n->data;
}
}
else{
//当前是超大模块 超过8192大小
t = &m_Data[nKey];
//根节点为空 直接申请内存
if (t->data == nullptr)
{
t->nUnit = nSize;
t->nCount = 1;
t->data = new char[nSize];
#ifdef UseMulThread
m_DataMutex.unlock();
#endif
return t->data;
}
else{
//申请内存 并添加到超大模块链表中
MemoryData * newdata = CreateBigMeo(nSize);
if (newdata == nullptr)
{
#ifdef UseMulThread
m_DataMutex.unlock();
#endif
return nullptr;
}
#ifdef UseMulThread
m_DataMutex.unlock();
#endif
return newdata->data;
}
}
#ifdef UseMulThread
m_DataMutex.unlock();
#endif
return nullptr;
}
MemoryData * MemoryPool::CreateBigMeo(int nSize)
{
/*MemoryData *t = &m_Data[MemBig];
while (t)
{
if (t->nCount == 0 && t->data != nullptr && t->nUnit >= nSize)
{
t->nCount = 1;
return t;
}
t = t->next;
}*/
//申请超大内存
MemoryData * dd = new MemoryData;
dd->nUnit = nSize;
dd->nCount = 1;
dd->data = new char[nSize];
if (dd->data == nullptr)
{
delete dd;
dd = nullptr;
return nullptr;
}
//添加到链表中
MemoryData *t = &m_Data[MemBig];
while (t && t->next)
{
t = t->next;
}
t->next = dd;
return dd;
}
//重新分配大模块
MemoryData * MemoryPool::CreateMeo(int nKey)
{
//当前模块单位大小
int nUint = GetMemSize(nKey);
MemoryData * dd = new MemoryData;
if (nUint > 0)
{
dd->nUnit = nUint;
dd->nCount = m_nCount;
dd->data = new char[dd->nUnit * dd->nCount];
//分配失败 数量减半重新申请
while (dd->nCount > 0 && dd->data == nullptr)
{
dd->nCount /= 2;
dd->data = new char[dd->nUnit * dd->nCount];
}
//将未使用小块 添加到未使用链表中
for (int j = 0; j < dd->nCount; j++)
{
MemoryNode * n = new MemoryNode;
n->data = dd->data + j * dd->nUnit;
if (dd->free == nullptr)
{
dd->free = n;
dd->freeLast = n;
}
else
{
dd->freeLast->next = n;
dd->freeLast = n;
}
}
}
else{
delete dd;
dd = nullptr;
return nullptr;
}
return dd;
}
bool MemoryPool::FreeOnKey(void *address, int nKey)
{
//是超大内存
if (nKey == MemBig)
{
MemoryData *t = &m_Data[nKey];
MemoryData *father = t;
while (t)
{
if (t->data == address)
{
if (t == &m_Data[nKey])
{
delete m_Data[nKey].data;
m_Data[nKey].data = nullptr;
}
else{
father->next = t->next;
delete t->data;
t->data = nullptr;
delete t;
t = nullptr;
}
return true;
}
father = t;
t = t->next;
}
}
else{
//不是超大内存 查找当前模块
MemoryData *t = &m_Data[nKey];
while (t)
{
int a = (int)t->data;
int b = (int)(t->data + t->nUnit * t->nCount);
//地址的范围
int min = (a > b ? b : a);
int max = (a > b ? a : b);
int id = (int)address;
//当前释放地址在 当前模块地址范围内
if (id >= min && id <= max)
{
//
MemoryNode *inFind = t->use;
MemoryNode *father = inFind;
//从使用链表中删除当前小块 加入到未使用链表中
while (inFind)
{
if (inFind->data == address)
{
t->freeLast->next = inFind;
t->freeLast = inFind;
if (father == t->use)
{
t->use = nullptr;
}
else{
father->next = inFind->next;
}
return true;
}
father = inFind;
inFind = inFind->next;
}
}
t = t->next;
}
}
return false;
}
//释放内存
bool MemoryPool::FreeMeo(void *address, int nSize)
{
if (address == nullptr) return false;
//std::cout << "释放大小 = " << nSize << std::endl;
#ifdef UseMulThread
m_DataMutex.lock();
#endif
if (nSize != 0)
{
//释放内存大小对应的模块id
int nKey = GetMemKey(nSize);
//释放对应模块的内存
bool result = FreeOnKey(address, nKey);
#ifdef UseMulThread
m_DataMutex.unlock();
#endif
return result;
}
else{
//不知道释放大小 从各个模块中依次查找
for (int i = Mem4; i <= MemBig; i++)
{
if (FreeOnKey(address, i))
{
#ifdef UseMulThread
m_DataMutex.unlock();
#endif
return true;
}
}
}
#ifdef UseMulThread
m_DataMutex.unlock();
#endif
return false;
}
//销毁内存池
void MemoryPool::DestoryMeo()
{
for (int i = 0; i < MemCount; i++)
{
MemoryData *first = &m_Data[i];
while (first)
{
if (first->data)
{
delete[] first->data;
first->data = nullptr;
}
MemoryNode * second = first->free;
while (second)
{
MemoryNode *freenode = second;
second = second->next;
delete freenode;
freenode = nullptr;
}
if (first->freeLast)
{
delete first->freeLast;
first->freeLast = nullptr;
}
second = first->use;
while (second)
{
MemoryNode *freenode = second;
second = second->next;
delete freenode;
freenode = nullptr;
}
MemoryData *mustFree = first;
first = first->next;
if (mustFree != &m_Data[i])
{
delete mustFree;
mustFree = nullptr;
}
else{
m_Data[i].next = nullptr;
}
}
}
}
内存池
最新推荐文章于 2024-09-10 09:05:46 发布