分配器?
描述
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;