#ifndef MEMORYPOOL_H
#define MEMORYPOOL_H
#include<mutex>
static const int __align = 8;
static const int __max_bytes = 512;
static const int __number_of_free_lists = __max_bytes / __align;//内存池的数量
static const int __number_add_nodes = 20;
class MemoryPool
{
public:
static MemoryPool& getInstance()
{
static MemoryPool pool;
return pool;
}
void *allocMemory(size_t nSize);//分配内存
void freeMemory(void*&pMem,size_t nsize);//释放内存
private:
union MemNode
{
char index;//释放时,用于记录在那个内存池
MemNode* _next;//分配创建内存时用于连接各个内存块的
};
struct BigBloke//大内存块的连接地址
{
BigBloke *pPre;
BigBloke *pNext;
char index;//那个内存池
char num; //当前内存块的空间大小
};
MemoryPool();
~MemoryPool();
int RoundUp(int size, int align = __align)
{
return ((size + align - 1) & ~(align - 1));//向8(align)字节的内存空间靠齐
}
int FreeListIndex(int size, int align = __align)
{
return (size + align - 1) / align - 1;//找到对应分配内存对应内存池下标
}
MemNode* MallocMemory(int size);//分配大内存块
void FreeMemory(int index);//释放大内存块
private:
size_t free_memory_size[__number_of_free_lists];//各个内存池的容量
size_t use_memory_size[__number_of_free_lists];//各个内存池的使用情况
MemNode* _free_list[__number_of_free_lists]; //可用内存池列表
BigBloke *pStart;
BigBloke *pEnd;
protected:
std::recursive_mutex _mutex;
};
void *operator new(size_t size);
void operator delete(void *p, size_t size);
void *operator new[](size_t size);
void operator delete[](void *p, size_t size);
#endif // MEMORYPOOL_H
//=================================================================================================
#include "Memorypool.h"
MemoryPool::MemoryPool()
{
for (size_t i = 0; i < __number_of_free_lists; ++i)
{
free_memory_size[i] = 0;
use_memory_size[i] = 0;
_free_list[i] = nullptr;
}
pStart = nullptr;
pEnd = nullptr;
}
MemoryPool::~MemoryPool()
{
BigBloke *temp;
while (pStart!=nullptr)
{
temp = pStart;
pStart = pStart->pNext;
free(temp);
}
}
void *MemoryPool::allocMemory(size_t nSize)//分配内存
{
int malloc_size = nSize;
if (malloc_size > __max_bytes)
{
//大内存从系统中分配空间
void* bytes = malloc(malloc_size);
return bytes;
}
//小内存从系统中分配空间
int index = FreeListIndex(malloc_size);
std::unique_lock<std::recursive_mutex> lock(_mutex);
MemNode** my_free = &(_free_list[index]);
MemNode* result = *my_free;
if (result == nullptr)
{
//内存池空间已经用完,需重新分配
result = MallocMemory(RoundUp(malloc_size));
if (result == nullptr)
{
//分配内存失败
return nullptr;
}
}
*my_free = result->_next;
use_memory_size[index] += 1;
char *ret = (char*)result;
return ret;
}
void MemoryPool::freeMemory(void*&pMem, size_t nsize)//释放内存
{
if (pMem == nullptr)
return;
if (nsize>__max_bytes) //从系统中分配的大空间
{
free(pMem);
return;
}
int index = FreeListIndex(nsize);
//从内存池分配空间的释放
MemNode* node = (MemNode*)pMem;
std::unique_lock<std::recursive_mutex> lock(_mutex);
MemNode** my_free = &(_free_list[index]);
node->_next = *my_free;
*my_free = node;
pMem = nullptr;
use_memory_size[index] -= 1;
//当使用内存小到分配内存的一半时,释放一个大内存
if ((free_memory_size[index]>(__number_add_nodes*2))&&(use_memory_size[index] < free_memory_size[index] * 0.5))
{
FreeMemory(index);
}
}
MemoryPool::MemNode* MemoryPool::MallocMemory(int size)//每次内存池容量增加会以当前容量的0.5倍增加
{
if (size % 8 != 0 || size <= 0)
return nullptr;
int num = 0;
int index = FreeListIndex(size);
//起初设定内存大小为20个内存块
if (free_memory_size[index] == 0)
{
num = __number_add_nodes;
}
else
{
num = free_memory_size[index] * 0.5;
}
BigBloke *malloc_mem = (BigBloke *)malloc(num*size+sizeof(BigBloke));
if (nullptr == malloc_mem)
return nullptr;
//将大内存块放人链表以便释放
malloc_mem->index = index;
malloc_mem->num = num;
malloc_mem->pPre = pEnd;
malloc_mem->pNext = nullptr;
if (pEnd != nullptr)
{
pEnd->pNext = malloc_mem;
}
pEnd = malloc_mem;
if (pStart == nullptr)
{
pStart = malloc_mem;
}
MemNode *re=(MemNode*)((char *)malloc_mem+sizeof(BigBloke));
//内存连接
MemNode *pNext = re,*temp=nullptr;
for(size_t i=1;i<num;++i)
{
temp = (MemNode *)((char*)re + i*size);
temp->_next = nullptr;
pNext->_next = temp;
pNext = temp;
}
//修改内存池的大小
free_memory_size[FreeListIndex(size)] += num;
return re;
}
void MemoryPool::FreeMemory(int index)//释放大内存块
{
BigBloke *p = pEnd;
while (p != nullptr)
{
if (p->index == index)
{
BigBloke *pre = p->pPre;
if (pre != nullptr)
{
pre->pNext = p->pNext;
if(p->pNext!=nullptr)
p->pNext->pPre = pre;
}
else//删除头
{
pStart = p->pNext;
if (pStart == nullptr)
{
pEnd = nullptr;
}
}
free_memory_size[index] -= p->num;
free(p);//删除内存大块
break;
}
p = p->pPre;
}
}
void *operator new(size_t size)
{
return MemoryPool::getInstance().allocMemory(size);
}
void operator delete(void *p,size_t size)
{
MemoryPool::getInstance().freeMemory(p,size);
}
void *operator new[](size_t size)
{
return MemoryPool::getInstance().allocMemory(size);
}
void operator delete[](void *p, size_t size)
{
MemoryPool::getInstance().freeMemory(p,size);
}