分配器
描述
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 \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
使用创建内存池。这样内存就可在进程间共享了。每次更新时,内存都被更新到后备存储(backing store)。
ACE_Lite_MMAP_Memory_Pool
ACE_LITE_MMAP_MEMORY_POOL
使用创建内存池。不像前面的映射,它不做后备存储更新。代价是较低可靠性。
ACE_Sbrk_Memory_Pool
ACE_SBRK_MEMORY_POOL
使用调用创建内存池。
ACE_Shared_Memory_Pool
ACE_SHARED_MEMORY_POOL
使用系统V 调用创建内存池。
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> Allocator;
阅读(2143) | 评论(0) | 转发(0) |