作者:橙子 来源:博客园 酷勤网收集 2008-01-17
分配器描述
ACE_Allocator
ACE中的分配器类的接口类。这些类使用继承和动态绑定来提供灵活性。
ACE_Static_Allocator
该分配器管理固定大小的内存。每当收到分配内存的请求时,它就移动内部指针、以返回内存chunk(“大块”)。它还假定内存一旦被分配,就再也不会被释放。
ACE_Cached_Allocator
该分配器预先分配内存池,其中含有特定数目和大小的内存chunk。这些chunk在内部空闲表(free list)中进行维护,并在收到内存请求(malloc())时被返回。当应用调用free()时,chunk被归还到内部空闲表、而不是OS中。
ACE_New_Allocator
为C++ new和delete操作符提供包装的分配器,也就是,它在内部使用new和delete操作符,以满足动态内存请求。
#include " ace/Malloc.h "
// A chunk of size 1K is created. In our case we decided to use a simple array
// as the type for the chunk. Instead of this we could use any struct or class
// that we think is appropriate.
typedef char MEMORY_BLOCK[ 1024 ];
// Create an ACE_Cached_Allocator which is passed in the type of the
// “chunk” that it must pre-allocate and assign on the free list.
// Since the Cached_Allocator is a template class we can pretty much
// pass it ANY type we think is appropriate to be a memory block.
typedef ACE_Cached_Allocator < MEMORY_BLOCK,ACE_SYNCH_MUTEX > Allocator;
class MessageManager

{
public :
// The constructor is passed the number of chunks that the allocator
// should pre-allocate and maintain on its free list.
MessageManager( int n_blocks):
allocator_(n_blocks),message_count_( 0 )

{
mesg_array_ = new char * [n_blocks];
} // Allocate memory for a message using the Allocator. Remember the message
// in an array and then increase the message count of valid messages
// on the message array.
void allocate_msg( const char * msg)
{
mesg_array_[message_count_] = ( char * )allocator_.malloc(ACE_OS::strlen(msg) + 1 );
ACE_OS::strcpy(mesg_array_[message_count_],msg);
message_count_ ++ ;
}

// Free all the memory that was allocated. This will cause the chunks
// to be returned to the allocator’s internal free list
// and NOT to the OS.
void free_all_msg()

{
for ( int i = 0 ;i < message_count_;i ++ )
allocator_.free(mesg_array_[i]);

message_count_ = 0 ;
}

// Just show all the currently allocated messages in the message array.
void display_all_msg()

{
for ( int i = 0 ;i < message_count_;i ++ )
ACE_OS::printf( " %s\n " ,mesg_array_[i]);
}

private :
char ** mesg_array_;
Allocator allocator_;
int message_count_;
} ;

int main( int argc, char * argv[])

{

char message[ 512 ] =
{ 0 } ;
if (argc < 2 )

{
ACE_DEBUG((LM_DEBUG, " Usage: %s <Number of blocks>\n " , argv[ 0 ]));
exit( 1 );
}

int n_blocks = ACE_OS::atoi(argv[ 1 ]);

// Instantiate the Memory Manager class and pass in the number of blocks
// you want on the internal free list.
MessageManager mm(n_blocks);
// Use the Memory Manager class to assign messages and free them.
// Run this in your favorite debug environment and you will notice that the
// amount of memory your program uses after Memory Manager has been
// instantiated remains the same. That means the Cached Allocator
// controls or manages all the memory for the application.
// Do forever.
while ( 1 )

{
// allocate the messages somewhere
ACE_DEBUG((LM_DEBUG, " \n\n\nAllocating Messages\n " ));

for ( int i = 0 ; i < n_blocks;i ++ )
{
ACE_OS::sprintf(message, " Message %d: Hi There " ,i);
mm.allocate_msg(message);
}

// show the messages
ACE_DEBUG((LM_DEBUG, " Displaying the messages\n " ));
Sleep( 2 );
mm.display_all_msg();

// free up the memory for the messages.
ACE_DEBUG((LM_DEBUG, " Releasing Messages\n " ));
Sleep( 2 );

mm.free_all_msg();
}
return 0 ;
}
内存池:
ACE_MMAP_Memory_Pool
ACE_MMAP_MEMORY_POOL
使用<mmap(2)>创建内存池。这样内存就可在进程间共享了。每次更新时,内存都被更新到后备存储(backing store)。
ACE_Lite_MMAP_Memory_Pool
ACE_LITE_MMAP_MEMORY_POOL
使用<mmap(2)>创建内存池。不像前面的映射,它不做后备存储更新。代价是较低可靠性。
ACE_Sbrk_Memory_Pool
ACE_SBRK_MEMORY_POOL
使用<sbrk(2)>调用创建内存池。
ACE_Shared_Memory_Pool
ACE_SHARED_MEMORY_POOL
使用系统V <shmget(2)>调用创建内存池。
Memory_Pool
内存可在进程间共享。
ACE_Local_Memory_Pool
ACE_LOCAL_MEMORY_POOL
通过C++的new和delete操作符创建局部内存池。该池不能在进程间共享。
#include " ace/Malloc.h "
#include " ace/Malloc_T.h "
#include " ace/Null_Mutex.h "
#include < ACE / MMAP_Memory_Pool.h >
typedef ACE_Malloc < ACE_MMAP_Memory_Pool,ACE_Null_Mutex > Malloc;
void ReadData();
void WriteData();
Malloc * g_mem;
int main( int arn, char ** arc)
{
ACE_MMAP_Memory_Pool_Options options(ACE_DEFAULT_BASE_ADDR,
ACE_MMAP_Memory_Pool_Options::ALWAYS_FIXED,
1024 * 10000 );
ACE_NEW_RETURN(g_mem,Malloc( " abc " , " abc " , & options), - 1 );
if ( arn > 1 )
{
ReadData();
}
else
{
WriteData();
}
system( " pause " );
g_mem -> sync();
delete g_mem;
return 0 ;
}
void ReadData()
{
char msg[ 32 ] =
{ 0 } ;
void * data;
for ( int i = 0 ;i < 10000 ;i ++ )
{
sprintf(msg, " MSG: %d " ,i);
if (g_mem -> find(msg,data) != - 1 )
{
ACE_DEBUG((LM_INFO, " %s\n " ,( char * )data));
}
}
}
void WriteData()
{
for ( int i = 0 ;i < 10000 ;i ++ )
{
char * buff = ( char * )g_mem -> malloc( 1024 );
if (buff != NULL)
{
sprintf(buff, " MSG: %d " ,i);
g_mem -> bind(buff,( void * )buff);
}
}
}
通过分配器接口使用Malloc类
大多数ACE中的容器类都可以接受分配器对象作为参数,以用于容器内的内存管理。因为某些内存分配方案只能用于ACE_Malloc类集,ACE含有一个适配器模板类ACE_Allocator_Adapter,它将ACE_Malloc类适配到ACE_Allocator接口。也就是说,在实例化这个模板之后创建的新类可用于替换任何ACE_Allocator。例如:
typedef ACE_Allocator_Adapter<ACE_Malloc<ACE_SHARED_MEMORY_POOL,ACE_Null_Mutex>> Allocator;
来自:http://www.cppblog.com/lovelypig/archive/2006/08/30/11851.aspx

