概述
- 4kb內存對齊,內存分配以4kb爲基準.內存分配都是按照一定的值32,16,4等,少了也這樣分。內存的設計原理:就是指針得到不斷移動,設計到指針核心就移動來移到不同的內存區.連續的內存空間分配有申請必須有釋放對於內存操作.
重載全局運算符
/*
* @Author: power
* @Date: 2020-01-28 10:41:36
* @LastEditTime : 2020-01-28 15:13:23
* @LastEditors : Please set LastEditors
* @Description: In User Settings Edit
* @FilePath: /test/Alloctor.cpp
*/
// #include "Alloctor.hpp"
#include <stdlib.h>
#include "MemoryPoll.hpp"
void* operator new(size_t nSize)
{
return MemoryMgr::Instance().allocMem(nSize);
}
void operator delete(void* p)
{
MemoryMgr::Instance().freeMem(p);
}
void* operator new[](size_t nSize)
{
return MemoryMgr::Instance().allocMem(nSize);
}
void operator delete[](void* p)
{
MemoryMgr::Instance().freeMem(p);
}
void* mem_alloc(size_t size)
{
return malloc(size);
}
void mem_free(void *p)
{
free(p);
}
編寫內存塊和內存管理工具
/*
* @Author: power
* @Date: 2020-01-28 11:05:02
* @LastEditTime : 2020-01-28 14:42:11
* @LastEditors : Please set LastEditors
* @Description: In User Settings Edit
* @FilePath: /test/MemoryPoll.hpp
*/
#ifndef _MEMORYPOLL_H_
#define _MEMORYPOLL_H_
#define MAX_MEMORY_SZIE 128
#include <stdlib.h>
#include <assert.h>
#include <mutex>
#include <iostream>
class MemoryPoll;
class MemoryBlock
{
private:
/* data */
//預留字段
char c1;
char c2;
char c3;
public:
MemoryPoll* pAlloc;//所屬的內存池
MemoryBlock* pNext;//下一塊位置
int nID;//內存塊編號
int nRef;//內存塊編號
bool bPool;//是否在內存池中
};
class MemoryPoll
{
private:
/* data */
public:
MemoryPoll()
{
_pbuf = nullptr;
_pHeader = nullptr;
_nSize = 0;
_nBlockSize = 0;
}
~MemoryPoll()
{
if(_pbuf)
free(_pbuf);
}
//內存池申請
void* allocMemory(size_t nSize)
{
std::lock_guard<std::mutex> lg(_mutex);
if(!_pbuf)
{
initMemory();
}
MemoryBlock* pReturn = nullptr;
if(nullptr==_pHeader)
{
pReturn = (MemoryBlock*)malloc(nSize+sizeof(MemoryBlock));
pReturn->bPool = false;
pReturn->nID = -1;
pReturn->nRef = 1;
pReturn->pAlloc = nullptr;
pReturn->pNext = nullptr;
}
else
{
pReturn = _pHeader;
_pHeader= _pHeader->pNext;
assert(0 == pReturn->nRef);
pReturn->nRef = 1;
}
return ((char*)pReturn + sizeof(MemoryBlock));
}
void freeMemory(void* pMem)
{
MemoryBlock* pBlock = (MemoryBlock*)((char*)pMem-sizeof(MemoryBlock));
assert(1 == pBlock->nRef);
if(pBlock->bPool)
{
std::lock_guard<std::mutex> lg(_mutex);
if(--pBlock->nRef !=0)
{
return;//被佔用
}
pBlock->pNext = _pHeader;
_pHeader = pBlock;
}
else
{
if(--pBlock->nRef!=0)
{
return;
}
free(pBlock);
}
}
//初始化內存池
void initMemory()
{
//斷言
assert(nullptr==_pbuf);
if(_pbuf)
return;
//計算內存池的大小
size_t realSize = _nSize + sizeof(MemoryBlock);//真實每塊內存的大小
size_t bufSize = realSize*_nBlockSize;//內存池的總大小
_pbuf =(char*)malloc(bufSize);
//初始化內存池
_pHeader = (MemoryBlock*)_pbuf;
_pHeader->bPool = true;
_pHeader->nID = 0;
_pHeader->nRef = 0;
_pHeader->pAlloc = this;
_pHeader->pNext = nullptr;
//遍歷內存塊進行初始化
MemoryBlock* pTemp1 = _pHeader;
for (size_t i = 1; i < _nBlockSize; i++)
{
MemoryBlock* pTemp2 = (MemoryBlock*) (_pbuf+i*realSize);
pTemp2->nID = i;
pTemp2->bPool = true;
pTemp2->nRef = 0;
pTemp2->pAlloc = this;
pTemp2->pNext = nullptr;
pTemp1->pNext = pTemp2;
pTemp1 = pTemp2;
}
}
protected:
//內存池地址即維護一塊大內存
char* _pbuf;
//首部位置
MemoryBlock* _pHeader;
//內存池的大小
size_t _nSize;
//內存單元的數量
size_t _nBlockSize;
std::mutex _mutex;
};
template<size_t nSize,size_t nBlockSize>
class MemoryAlloctor:public MemoryPoll
{
private:
/* data */
public:
MemoryAlloctor()
{
const size_t n = sizeof(void*);
_nSize = (nSize/n)*n+(nSize % n ? n : 0);//規定以4的倍數分配內存空間
_nBlockSize = nBlockSize;
}
};
//內存池管理工具
class MemoryMgr
{
private:
/* data */
MemoryAlloctor<64,1000> _mem64;
MemoryAlloctor<128,1000> _mem128;
MemoryPoll* _szAlloc[MAX_MEMORY_SZIE+1];
public:
MemoryMgr()
{
init_szAlloc(0,64,&_mem64);
init_szAlloc(65,128,&_mem128);
}
~MemoryMgr()
{
}
static MemoryMgr& Instance()
{
static MemoryMgr mgr;
std::cout<<"jinru"<<std::endl;
return mgr;
}
void init_szAlloc(int nBegin,int nEnd,MemoryPoll* pMemA)
{
for (int i = nBegin; i <= nEnd; i++)
{
/* code */
_szAlloc[i] = pMemA;
}
}
void* allocMem(size_t nSize)
{
if(nSize <= MAX_MEMORY_SZIE)
{
return _szAlloc[nSize]->allocMemory(nSize);
}
else
{
MemoryBlock* pReturn = (MemoryBlock*)malloc(nSize+sizeof(MemoryBlock));
pReturn->bPool = false;
pReturn->nID = -1;
pReturn->nRef = 1;
pReturn->pAlloc = nullptr;
pReturn->pNext = nullptr;
return ((char*)pReturn+sizeof(MemoryBlock));
}
}
//釋放內存
void freeMem(void*pMem)
{
MemoryBlock * pBlock = (MemoryBlock*)((char*)pMem-sizeof(MemoryBlock));
if (pBlock->bPool)
{
pBlock->pAlloc->freeMemory(pMem);
}
else
{
if(--pBlock->nRef == 0)
{
free(pBlock);
}
}
}
};
#endif // !_MEMORYPOLL_H_
進行測試
/*
* @Author: power
* @Date: 2020-01-28 14:37:44
* @LastEditTime : 2020-01-28 15:17:14
* @LastEditors : Please set LastEditors
* @Description: In User Settings Edit
* @FilePath: /test/MemoryTest.cpp
*/
#include <iostream>
#include "Alloctor.cpp"
int main(int argc, const char** argv) {
int*p = new int(8);
std::cout<<*p;
return 0;
}
測試結果
輸出8