winston 发表于 2010-2-3 17:31:49

ACE内存池

来自本站QQ群邮件。

// MemPoolDemo.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <ace/Malloc_T.h>
#include <ace/Local_Memory_Pool.h>
#include <ace/Thread_Mutex.h>
typedef ACE_Malloc<ACE_Local_Memory_Pool,ACE_Thread_Mutex> MEM_POOL;
//ACE_Cached_Allocator,构造函数ACE_Cached_Allocator (size_t n_chunks),创建n_chunks个固定长度的内存池,长度为sizeof(T),T为模板参数
//ACE_Dynamic_Cached_Allocator,构造函数ACE_Dynamic_Cached_Allocator (size_t n_chunks, size_t chunk_size),创建n_chunks个大小为chunk_size的内存池
#include <iostream>
using namespace std;
/*
需要做性能测试的,可以自己修改下源码
*/
int _tmain(int argc, _TCHAR* argv[])
{
{
size_t nChk = 1024*1024*100;
MEM_POOL mem;
char* p = (char*)mem.malloc(nChk);//分配100M
if (p != NULL)
{
   cout << "p != null" << endl;   
}
mem.free(p);//释放内存

//打开下面的注释,用断点跟踪会发现,循环10次内存不会增长,从第11次开始,每循环一次内存增加10M。MEM_POOL的内存是只增不减的,它自身没有内存大小的限制
for (int i = 0; i < 15;++i)
{
   const size_t nPerChk = 1024*1024*10;//10M
   mem.malloc(nPerChk);//分配了不调用free释放,
}
size_t nsize = 10;
p = (char*)mem.malloc(nsize);
if (p != NULL)
{
   cout << "p != null" << endl;
   strcpy(p,"0123456789");   
}

char* q = (char*)mem.malloc(nsize);
if (q != NULL)
{
   cout << "q != null" << endl;
   strcpy(q,"aaaaaaaaa");
}
cout << p << endl;
cout << q << endl;
cout << q - p << endl;
cout << p - q << endl;

}

{
struct Entry
{
   int a;
   char b;
};
size_t nCount = 1;
ACE_Cached_Allocator<Entry,ACE_Thread_Mutex> cch(nCount) ;//分配nCount个大小为sizeof(Entry)的块
Entry* p = (Entry*)cch.malloc();
p->a = 10;
p->b = 'a';
Entry* q = (Entry*)cch.malloc();//这里返回NULL
if (q == NULL)
{
   cout << "q == null" << endl;
}

cch.free(p);
Entry* r = (Entry*)cch.malloc();//上面释放p后,这里可以获得内存
if (r != NULL)
{
   cout << "r != null" << endl;
}
}
{
ACE_Dynamic_Cached_Allocator<ACE_Thread_Mutex> dynmem(1,10);//创建1个10字节的内存
size_t nbytes = 5;
char* p = (char*)dynmem.malloc(nbytes);//只检查nbytes不大于构造函数中传进去的10既可
if (p != NULL)
{
   cout << "p != null" << endl;
}
char* pNull = (char*)dynmem.malloc(nbytes);//上面没有释放,这里应该为NULL
if(pNull == NULL)
{
   cout << "p == null " << endl;
}
}
{
ACE_Static_Allocator<10> stamem;//分配10字节的内存
char* p = (char*)stamem.malloc(10);//从内存池中分配
if (p != NULL)
{
   cout << "p != null" << endl;
}
stamem.free(p);//这里并没有释放,也就是说,p是一次性的拥有了分配给他的10个字节,不能释放
p = (char*)stamem.malloc(10);
if (p == NULL)
{
   cout << " p == null" << endl;
}
}

return 0;
}

modern 发表于 2010-2-3 18:00:11

呵呵,我前一阵子也在尝试在工程中,引入ACE的内存池。
结合ACE_Cached_Allocator 使用ACE_Message_block
做10万次连续内存分配,再释放。
执行时间大概有2倍以上的提升,
CPU的占用率的提升也是比较明显的。

另外ACE提供的其他几种内存池也是比较有意思。
结合ACE_Malloc模版与Hash_Map使用也是非常强大的。

freeeyes 发表于 2010-3-19 11:08:25

我曾经自己写了一个内存池,在ACE下运行报错。
后来查了一下,ace在某些部分,有些是在lib里面new的,在lib外面delete的,导致问题的出现。
后来都换ace统一的内存池就好了。不过它的池确实只增长不减少,可能是考虑效率和碎片问题吧。

yoogera 发表于 2010-6-30 20:42:46

确实有用~~~~~~~~~~~~
页: [1]
查看完整版本: ACE内存池