一种内存管理器的实现方法

在软件设计和开发过程中,合理高效的使用内存,关乎软件执行的效率和性能,内存管理至关重要,下面一种方法可以对分配的内存进行回收再利用,提高内存使用率,c++代码如下:

memmgr.h

#ifndef __MEMMGR_H
#define __MEMMGR_H


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <iostream>
#include <string>
#include <vector>
#include <list>
#include "commondatastruct.h"


using namespace std;


//define data type
enum  MemoryType {B64_B,HALF_K,ONE_K,THREE_K,NO_MEM };
const int  BaseBlkNum=1; //must be 1   for add free policy to OS when occupy to much .SRC is 20


const size_t  B64 = 64;
const size_t  HalfK = 1024;
const size_t  OneK = 2048; //1024+ 512 = 1536
const size_t  ThreeK = 3072; //1024*3


const size_t MaxSizeForListB64 = 10000; //6.4M
const size_t MaxSizeForListB1K = 10000; //20000K,20M
const size_t MaxSizeForListBHalfK = 10000; //10000K,10M
const size_t MaxSizeForListB3K = 5000;  // 15000K,15M


class MemoryManager
{
public:
MemoryManager();
~MemoryManager();
void * Allocate(size_t len);
void  Free(void *obj,size_t sz);
void  OnTimer(time_t tm);
private:
void InitList(void * base,MemoryType mtype);
void CleanUp();


private:
list<void *>   b64ptrlist_;
list<void *>   b1kptrlist_;
list<void *>   bhalf1kptrlist_;
list<void *>   b3kptrlist_;
int newallocatecount_[THREE_K+1];
int reusedcount_[THREE_K+1];
int needcount_[THREE_K+1];
};


#endif



memmgr.cpp

#ifndef __MEMMGR_CPP
#define __MEMMGR_CPP


#include "memmgr.h"


using namespace std;




void MemoryManager::InitList(void * base,MemoryType mtype)
{
void *pbase = base;
int loop = 0;


if(B64_B==mtype)

//pbase+=64; 
newallocatecount_[B64_B]++;
while(loop<=BaseBlkNum-1) { b64ptrlist_.push_back(pbase); /*pbase+=B64;*/loop++;}
}
else
if(HALF_K==mtype)

//pbase+=512; 
newallocatecount_[HALF_K]++;
while(loop<=BaseBlkNum-1) { bhalf1kptrlist_.push_back(pbase); /*pbase+=HalfK;*/loop++;}
}
else
if(ONE_K == mtype)
{
//pbase+=1024; 
newallocatecount_[ONE_K]++;
while(loop<=BaseBlkNum-1) { b1kptrlist_.push_back(pbase); /*pbase+=OneK;*/loop++;}
}
else
if(THREE_K == mtype)
{
//pbase+=3072;
newallocatecount_[THREE_K]++;
while(loop<=BaseBlkNum-1) { b3kptrlist_.push_back(pbase); /*pbase+=ThreeK*/;loop++;}
}
};


MemoryManager::MemoryManager()
{
Logging::Info("[%d],%s,{%10u},Now MemoryManager creating ....\n",__LINE__,FileNameFormat(__FILE__),pThread_Self());

for(int i=0;i<=THREE_K;i++)
{
newallocatecount_[i]=0;
reusedcount_[i]=0;
needcount_[i]=0;
}
}


MemoryManager::~MemoryManager()
{
//CleanUp();
void *pbase = NULL;

//B64
list<void *>::iterator  it64 = b64ptrlist_.begin();
while(it64 != b64ptrlist_.end())
{
pbase = (*it64);
free(pbase);
pbase = NULL;
it64++;
}
    b64ptrlist_.clear();


//B1K
list<void *>::iterator  it1k = b1kptrlist_.begin();
while(it1k !=b1kptrlist_.end())
{
pbase =(*it1k);
free(pbase);
pbase = NULL;
it1k++;
}
b1kptrlist_.clear();


//BHalfK
list<void *>::iterator  ithalfk = bhalf1kptrlist_.begin();
while(ithalfk != bhalf1kptrlist_.end())
{
pbase = (*ithalfk);
free(pbase);
pbase = NULL;
ithalfk++;
}
bhalf1kptrlist_.clear();


//B3K
list<void *>::iterator  it3k = b3kptrlist_.begin();
while(it3k != b3kptrlist_.end())
{
pbase = (*it3k);
free(pbase);
pbase = NULL;
it3k++;
}
b3kptrlist_.clear();

Logging::Info("[%d],%s,{%10u},MemoryManager destroy ......\n",__LINE__,FileNameFormat(__FILE__),pThread_Self());
}


void * MemoryManager::Allocate(size_t len)
{
void *base=0;
void * blockptr=NULL;
MemoryType mtype = NO_MEM;
    
if(len< B64)
mtype = B64_B;
else
if(len < HalfK)
   mtype = HALF_K;
else
if(len < OneK)
mtype = ONE_K;
else
if(len < ThreeK)
mtype = THREE_K;


switch (mtype)
{
case B64_B:
{
if(b64ptrlist_.empty())
{
base = malloc(B64 * BaseBlkNum);
if(base==NULL)
{
//TraceAndAlarm cout<<"NOT enough memory to allocate"<<endl;
return NULL;
}
else
{
memset(base,0,B64*BaseBlkNum);
needcount_[B64_B]++;
newallocatecount_[B64_B]++;
return base;
}
}
else
{
blockptr = b64ptrlist_.front();
b64ptrlist_.pop_front();
needcount_[B64_B]++;
return blockptr;
}
break;
}


case HALF_K:
{
if(bhalf1kptrlist_.empty())
{
base = malloc(HalfK * BaseBlkNum);
if(base==NULL)
{
//TraceAndAlarm cout<<"NOT enough memory to allocate"<<endl;
return NULL;
}
else
{
memset(base,0,HalfK*BaseBlkNum);
needcount_[HALF_K]++;
newallocatecount_[HALF_K]++;
return base;
}
}
else
{
blockptr = bhalf1kptrlist_.front();
bhalf1kptrlist_.pop_front();
needcount_[HALF_K]++;
return blockptr;
}
break;
}


case ONE_K:
{
if(b1kptrlist_.empty())
{
base = malloc(OneK * BaseBlkNum);
if(base==NULL)
{
//Logging::Info("[%d],%s,{%10u},MemoryManager Allocate OneK  failed \n",__LINE__,FileNameFormat(__FILE__),pThread_Self());
return NULL;
}
else
{   
memset(base,0,OneK*BaseBlkNum);
needcount_[ONE_K]++;
newallocatecount_[ONE_K]++;
return base;
}
}
else
{
blockptr = b1kptrlist_.front();
b1kptrlist_.pop_front();
needcount_[ONE_K]++;
return blockptr;
}
break;
}


case THREE_K:
{
if(b3kptrlist_.empty())
        {
base = malloc(ThreeK * BaseBlkNum);
if(base==NULL)
{
return NULL;
}
else
{   
memset(base,0,ThreeK*BaseBlkNum);
needcount_[THREE_K]++;
newallocatecount_[THREE_K]++;
return base;
}
}
else
{
blockptr = b3kptrlist_.front();
b3kptrlist_.pop_front();
needcount_[THREE_K]++;
return blockptr;
}
break;
}


default:
return NULL;


}


return NULL;


  /*  if(len<=B64) //block 64
{
if(b64ptrlist_.empty())
{
//base = new char[B64 * BaseBlkNum];
base = malloc(B64 * BaseBlkNum);
if(base==NULL)
{
//TraceAndAlarm cout<<"NOT enough memory to allocate"<<endl;
return 0;
}
else
{
memset(base,0,B64*BaseBlkNum);
//mempoollist_.push_back(base);
InitList(base,B64_B);
}


blockptr = b64ptrlist_.front();
b64ptrlist_.pop_front();
needcount_[B64_B]++;
return blockptr;
}
else
{
blockptr = b64ptrlist_.front();
b64ptrlist_.pop_front();
needcount_[B64_B]++;
return blockptr;
}
}
else
if(len<=HalfK) //block 512
{
if(bhalf1kptrlist_.empty())
{
//base = new char[HalfK * BaseBlkNum];
base = malloc(HalfK * BaseBlkNum);
if(base==NULL)
{
//TraceAndAlarm cout<<"NOT enough memory to allocate"<<endl;
return 0;
}
else
{
memset(base,0,HalfK*BaseBlkNum);
//mempoollist_.push_back(base);
InitList(base,HALF_K);
}

blockptr = bhalf1kptrlist_.front();
bhalf1kptrlist_.pop_front();
needcount_[HALF_K]++;
return blockptr;
}
else
{
blockptr = bhalf1kptrlist_.front();
bhalf1kptrlist_.pop_front();
needcount_[HALF_K]++;
return blockptr;
}
}
else 
if(len <=OneK)  //block 1500
{
if(b1kptrlist_.empty())
        {
        //base = new char[OneK * BaseBlkNum];
base = malloc(OneK * BaseBlkNum);
if(base==NULL)
{
//TraceAndAlarm cout<<"NOT enough memory to allocate"<<endl;
Logging::Info("[%d],%s,{%10u},MemoryManager Allocate OneK  failed \n",__LINE__,FileNameFormat(__FILE__),pThread_Self());
return NULL;
}
else
{   
memset(base,0,OneK*BaseBlkNum);
//mempoollist_.push_back(base);
InitList(base,ONE_K);
}

blockptr = b1kptrlist_.front();
b1kptrlist_.pop_front();
needcount_[ONE_K]++;
return blockptr;
}
else
{
blockptr = b1kptrlist_.front();
b1kptrlist_.pop_front();
needcount_[ONE_K]++;
return blockptr;
}
}
else
if(len <=ThreeK)  //block 3072
{
if(b3kptrlist_.empty())
        {
        //base = new char[ThreeK * BaseBlkNum];
base = malloc(ThreeK * BaseBlkNum);
if(base==NULL)
{
//TraceAndAlarm cout<<"NOT enough memory to allocate"<<endl;
return 0;
}
else
{   
memset(base,0,ThreeK*BaseBlkNum);
//mempoollist_.push_back(base);
InitList(base,THREE_K);
}

blockptr = b3kptrlist_.front();
b3kptrlist_.pop_front();
needcount_[THREE_K]++;
return blockptr;
}
else
{
blockptr = b3kptrlist_.front();
b3kptrlist_.pop_front();
needcount_[THREE_K]++;
return blockptr;
}
}


return 0;
*/
};


void  MemoryManager::Free(void *obj,size_t sz)

MemoryType mtype=NO_MEM;
    
if(sz<B64)
mtype = B64_B;
else
if(sz<HalfK)
   mtype = HALF_K;
else
if(sz<OneK)
mtype = ONE_K;
else
if(sz < ThreeK)
mtype = THREE_K;
                  
//statistic reuse memory
reusedcount_[mtype]++;


switch (mtype)
{
case B64_B:
memset(obj,0,B64);
b64ptrlist_.push_front(obj);
return;
case HALF_K:
memset(obj,0,HalfK);
bhalf1kptrlist_.push_front(obj);
return;
case ONE_K:
memset(obj,0,OneK);
b1kptrlist_.push_front(obj);
return;
case THREE_K:
memset(obj,0,ThreeK);
b3kptrlist_.push_front(obj);
return;
default:
free(obj);
obj = NULL;
return;


}
};


void MemoryManager::CleanUp()
{


};


void MemoryManager::OnTimer(time_t tm)
{
Logging::Info("{%10u},Mem Usage Info: B64 [size: %u,NC: %u, RU: %u, ND: %u], B1k [size: %u,NC: %u, RU: %u, ND: %u],  BhalfK [size: %u,NC: %u, RU: %u,ND: %u], B3K [size: %u,NC: %u, RU: %u, ND: %u] \n",pThread_Self(),b64ptrlist_.size(),newallocatecount_[B64_B]*BaseBlkNum,reusedcount_[B64_B],needcount_[B64_B],b1kptrlist_.size(),newallocatecount_[ONE_K]*BaseBlkNum,reusedcount_[ONE_K],needcount_[ONE_K],bhalf1kptrlist_.size(),newallocatecount_[HALF_K]*BaseBlkNum,reusedcount_[HALF_K],needcount_[HALF_K],b3kptrlist_.size(),newallocatecount_[THREE_K]*BaseBlkNum,reusedcount_[THREE_K],needcount_[THREE_K]);

for(int i=0;i<=THREE_K;i++)
{
newallocatecount_[i]=0;
reusedcount_[i]=0;
needcount_[i]=0;
}


//check if need to free some memory to OS
size_t   tmplistlen = b64ptrlist_.size();

//B64
if(tmplistlen > MaxSizeForListB64 *2)
{
size_t  tmplen = tmplistlen - MaxSizeForListB64; 
void *pbase = NULL;
while(tmplen > 1)
{
pbase = b64ptrlist_.front();
b64ptrlist_.pop_front();
free(pbase);
pbase = NULL;
tmplen--;
}
}


//B1K
tmplistlen = b1kptrlist_.size();
if( tmplistlen> MaxSizeForListB1K *2)
{
size_t  tmplen = tmplistlen - MaxSizeForListB1K;
void *pbase = NULL;
while(tmplen > 1 )
{
pbase = b1kptrlist_.front();
b1kptrlist_.pop_front();
if(pbase !=NULL)
{
free(pbase);
pbase = NULL;
}
tmplen--;
}
}

//BHalfK
tmplistlen = bhalf1kptrlist_.size();
if(tmplistlen > MaxSizeForListBHalfK *2)
{
size_t  tmplen = tmplistlen - MaxSizeForListBHalfK;
void *pbase = NULL;
while(tmplen > 1)
{
pbase = bhalf1kptrlist_.front();
bhalf1kptrlist_.pop_front();
free(pbase);
pbase = NULL;
tmplen--;
}
}


//B3K
tmplistlen = b3kptrlist_.size();
if(tmplistlen > MaxSizeForListB3K *2)
{
size_t  tmplen = tmplistlen - MaxSizeForListB3K;
void *pbase = NULL;
while(tmplen > 1)
{
pbase = b3kptrlist_.front();
b3kptrlist_.pop_front();
free(pbase);
pbase = NULL;
tmplen--;
}
}

}


#endif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值