这是试验性的程序, 虽然算法实现简弱, 当在编译器优化后实验结果,
性能比用全局new delete的内存管理好了很多,我这里有考虑到多线程
看来在大量使用内存分配的程序,用内存池是能够显著提高性能的;
有时间我会改进算法,有高手看到, 请指点一二, 我是非专业的, 算法方面很弱;
还有数组的内存分配遇到了一些问题;
以下数组的内存分配的一般模式
void * operator new[](size_t size);
void operator delete[](void *p, size_t size);
可惜的是new里的size和delete你的size在vc, bc下并不匹配(g++则一样, 比较好);
这是的分配数组是需要保存指针及对应的大小(一般用hash), 这要消耗不少时间;
#pragma warning(disable: 4530)
#pragma warning(disable: 4786)
#include <map>
#include <cassert>
#include <iostream>
#include <algorithm>
#include <exception>
#include <iomanip>
#include <list>
using namespace std;
#include <windows.h>
template<size_t PreAllocSize = 1024>
class MemoryPool
{
protected:
struct MemoryBlock
{
char *_Address;
size_t _Size;
MemoryBlock * _Next;
MemoryBlock(void *pbegin, size_t size) : _Address((char *)pbegin), _Size(size), _Next(NULL) { };
};
struct Lock
{
CRITICAL_SECTION &CS;
Lock(CRITICAL_SECTION &cs) : CS(cs) { EnterCriticalSection(&CS); }
~Lock() { LeaveCriticalSection(&CS); }
};
char _Buffer[PreAllocSize];
char *_Begin, *_End;
CRITICAL_SECTION _csLock;
list<MemoryBlock * > _MemoryList;
void CreateList()
{
_MemoryList.push_back(new MemoryBlock(_Begin, PreAllocSize));
}
void FreeList()
{
list< MemoryPool::MemoryBlock * >::iterator iter;
for(iter = _MemoryList.begin(); iter != _MemoryList.end(); iter ++)
delete (*iter);
_MemoryList.clear();
}
void *FFA_Alloc(size_t size)// First fit algorithm
{
char *p = NULL;
list< MemoryPool::MemoryBlock * >::iterator iter;
for(iter = _MemoryList.begin(); iter != _MemoryList.end(); iter ++)
{
if(size < (*iter)->_Size)
{
p = (*iter)->_Address, (*iter)->_Address += size, (*iter)->_Size -= size;
break;
}
else
{
if(size == (*iter)->_Size)
{
p = (*iter)->_Address;
delete (*iter);
_MemoryList.erase(iter);
break;
}
}
}
return p;
}
bool FFA_Free(char *p, size_t size)
{
if(p < _Begin || p + size > _End)
return false;
list< MemoryPool::MemoryBlock * >::iterator iter, temp_iter;
for(iter = _MemoryList.begin(); iter != _MemoryList.end(); iter ++)
{
if(p < (*iter)->_Address) //find the insert point
{
if(p + size > (*iter)->_Address)//error
return false;
if(iter == _MemoryList.begin())
{
if(p + size == (*iter)->_Address) //union next_node
(*iter)->_Address = p, (*iter)->_Size += size;
else //insert
_MemoryList.insert(iter, new MemoryBlock(p, size));
}
else
{
temp_iter = iter, temp_iter--; //get pre_node
if((*temp_iter)->_Size + (*temp_iter)->_Address == p) //must union pre_node
{
if(p + size == (*iter)->_Address)//union next_node and pre_node
{
(*temp_iter)->_Size += size + (*iter)->_Size ;
_MemoryList.erase(iter);
}
else //just union pre_node
(*temp_iter)->_Size += size;
}
else
{
if(p + size == (*iter)->_Address)//union next_node
(*iter)->_Size += size, (*iter)->_Address = p;
else
_MemoryList.insert(iter, new MemoryBlock(p, size));
}
}
return true;
}// if(p < (*iter)->_Begin)
} //for
if(_MemoryList.size() == 0) // null list
_MemoryList.insert(_MemoryList.end(), new MemoryBlock(p, size));
else //push back of list
{
list< MemoryPool::MemoryBlock * >::reverse_iterator r_iter = _MemoryList.rbegin();
if((*r_iter)->_Size + (*r_iter)->_Address == p) //must union pre_node
(*r_iter)->_Size += size;
else
_MemoryList.insert(_MemoryList.end(), new MemoryBlock(p, size));
}
return true;
}
void *BFA_Alloc(size_t size)// Best fit algorithm
{
}
bool BFA_Free(char *p, size_t size)
{
}
void *WFA_Alloc(size_t size)// Worst fit algorithm
{
}
bool WFA_Free(char *p, size_t size)
{
}
public:
MemoryPool()// : _MemoryHash(PreAllocSize / 16)
{
_Begin = _Buffer, _End = _Buffer + PreAllocSize;
InitializeCriticalSection(&_csLock);
CreateList();
}
~MemoryPool()
{
DeleteCriticalSection(&_csLock);
FreeList();
}
void *Alloc(size_t size)
{
Lock lock(_csLock);
void *p = FFA_Alloc(size);
return p ? p : malloc(size);
}
void Free(void *address, int size)
{
Lock lock(_csLock);
if(!size)
size = 1;
if(!FFA_Free((char *)address, size))
{
printf("\nfree error : address %p size %d\n", address, size);
free(address);
}
}
void PrintList()
{
printf("\n");
int i;
if(_MemoryList.size() == 0)
{
printf("no memory!\n");
return;
}
list< MemoryPool::MemoryBlock * >::iterator iter;
for(i = 0, iter = _MemoryList.begin(); iter != _MemoryList.end(); iter ++, i ++)
printf("%d : Address %p offset %d, size %d;\n",
i, (*iter)->_Address, (*iter)->_Address - _Begin, (*iter)->_Size);
}
};
class Object
{
public:
static MemoryPool<2 * 1024 * 1024> _MP;
void * operator new (size_t size)
{
return _MP.Alloc(size);
};
void operator delete(void * p, size_t size)
{
_MP.Free(p, size);
};
};
MemoryPool<2 * 1024 * 1024> Object::_MP;
int main(int argc, char* argv[])
{
int i;
Object **x = new Object *[1000000];
int bt = GetTickCount();
for(i = 0 ; i < 1000000; i++)
x[i] = new Object();
for( i = 0 ; i < 1000000; i++)
delete x[i];
cout << "使用内存池 " << GetTickCount() - bt << endl;
bt = GetTickCount();
for(i = 0 ; i < 1000000; i++)
x[i] = ::new Object[10];
for( i = 0 ; i < 1000000; i++)
::delete x[i];
cout << "使用全局NEW " << GetTickCount() - bt << endl;
return 0;
}
本文地址:http://com.8s8s.com/it/it24631.htm