有一个结论是: 普通对象进行初始化所需的时间超过了对其进行分配和释放所需的时间
我写了一个简单的对象缓冲分配器。可以把某一种类型的对象cache在堆内存里,下次在用的时候,可以直接用,理想的“直接用”的意思是这个对象还存在,用的时候需要调用设计好的setup函数。
有的项目里对象频繁的船舰销毁。在操作系统里早就有这个的情况的解决办法了。但是应用程序如果避免这个情况呢?我还没有找到这个方面的代码例子。这个分配器也许没有什么用处,但是至少证明这个想法的可行性。
#ifndef _ALLOCATOR_H_
#define _ALLOCATOR_H_
#include<iostream>
#include<stdlib.h>
#include<new>
using namespace std;
typedef struct cache_s {
void *pMem;
void *end;
struct cache_s *nextp;
void *freeptr;
unsigned short inused;
unsigned short size;
} cache_t;
/*
* the bufctl type must be very very small,
* control very object memory,like they head.at begin of the object address.
* @flas:
* AA55=used
* 55AA=unused
*/
typedef struct bufctl_s {
union {
struct bufctl_s *buf_nextp;
unsigned short inused;
} u;
} bufctl_t;
template<class T>
class objalloc{
public:
objalloc(){};
~objalloc(){};
void cache_init();
void *get_free_mem(size_t size);
T* create_object();
void free_object(T* p);
void _free_object(T* p,size_t size);
inline void construct(T* p)
{
::new (p) T();
}
inline void destroy(T* pointer)
{
pointer->~T();
}
private:
struct cache_s *free_list;
enum { _INITOBJSIZE=4};
enum { _CACHESIZE=4};
};
/*
*init the cache ,
*
|cache|cache|cache|......|
*/
template <class T>
void objalloc<T>::cache_init()
{
//This will init _CACHESIZE*4 T type object
struct cache_s *caches, *first,*seacher;
void *p;
char *cp;
int i;
cout<<"The cache size is"<<sizeof(cache_s)<<endl;
first = caches = (struct cache_s *)malloc(sizeof(cache_s)*_CACHESIZE);
//memset(first,0,sizeof(cache_s)*_CACHESIZE);
for (i = _CACHESIZE; i > 1; i--) {
caches->nextp = caches+1;
caches++;
}
free_list = first;
// caches->nextp = free_list;
caches->nextp=NULL;
for (seacher = free_list; seacher; seacher = seacher->nextp)
{
//cout<<" i am here"<<seacher<<"freeptr "<<seacher->freeptr<<endl;
seacher->pMem=p=(char *)malloc(sizeof(T)*_INITOBJSIZE);
seacher->inused=0;
seacher->end=(char *)p+sizeof(T)*_INITOBJSIZE;
seacher->freeptr=p;
cp=(char *)p;
for (i=_INITOBJSIZE; i > 1; i--)
{
*((char **) cp) = cp + sizeof(T);
cp += sizeof(T);
}
*((char **) cp) = 0;
}
}
/*
*create a object of Type T,search the free list memeory,and find one,construt object on it
*/
template <class T>
T* objalloc<T>::create_object()
{
struct cache_s *cache;
void *p;
T* objp;
for (cache = free_list; cache; cache = cache->nextp)
{
if (cache->freeptr)
break;
}
if(!cache)
{
cout<<"out momory,using the system"<<endl;
objp=(T*)malloc(sizeof(T));
construct(objp);
return objp;
}
p=(void *)cache->freeptr;
cache->freeptr= *((void **)p);
objp=(T*)p;
cout<<"Find a free address="<<p<<","<<"the next free address="<<cache->freeptr<<endl;
construct(objp);
return objp;
}
/*
*Free the object ,not delete the memory.just put the memory into freelist
*then other object can use it.
*/
template <class T>
void objalloc<T>::free_object(T* p)
{
_free_object(p,sizeof(T));
}
template <class T>
void objalloc<T>::_free_object(T *p,size_t size)
{
cache_s *cache;
char *ptr;
if(p==NULL)
{
cout<<"null por"<<endl;
return;
}
for (cache = free_list; cache; cache = cache->nextp)
{
if (cache->pMem<p&&cache->end>p)
{
cout<<" got the pointer "<<endl;
destroy(p);
//cache->inused--;
ptr=(char *)p;
*((void **)ptr)=cache->freeptr;
cache->freeptr=(void *)p;
return ;
}else{
cout<<"Must be system memory,so delete it"<<endl;
free(p);
return ;
}
}
}
#endif//end define _ALLOCATOR_H_
使用方法:
#include "objalloc.h"
class A{
public:
A(){};
A(int a):_a(a){cout<<"constructor"<<endl;}
~A(){cout<<"destruct"<<endl;}
void print()
{
cout<<"hello world!"<<endl;
}
void set(int a){ _a=a;};
private:
int _a;
};
int main()
{
objalloc<A> oalloc;
oalloc.cache_init();
A *p=new A();
for(int i=0;i<10;i++)
{
A *p=oalloc.create_object();
cout<<"the object address="<<p<<endl;
p->print();
//oalloc.free_object(p);
}
oalloc.free_object(p);
//
return 0;
}
这个例子里,首先分配一个10个A类型的对象。如果这10对象操作了cache里的对象,就需要想系统要资源了。
销毁一个对象,只是把这个对象的空间返回给freelist而不销毁这个空间。下次还可以用这个空间。
这里还有很多缺点和不完善的地方。希望大家给点意见。
1)不能动态的扩大这个cache buffer的空间。这个空间是程序里 _INITOBJSIZ和_CACHESIZE确定
2)free 一个对象,仍然要执行析构函数。很希望能像slab一样,每个对象定义个desctruct函数,把要释放的资源释放,比如锁。
3)类型局限性,这个分配器是一个模板类,也就是每个对象都要定义一个分配器对象。
希望以后能逐渐改善这些不足。也希望大家给点意见。