Pool分配是一種分配內(nèi)存方法,用于快速分配同樣大小的內(nèi)存塊,
尤其是反復分配/釋放同樣大小的內(nèi)存塊的情況。
1. pool
快速分配小塊內(nèi)存,如果pool無法提供小塊內(nèi)存給用戶,返回0。
Example:
void func()
{
boost::pool<> p(sizeof(int));
^^^^^^^^^^^
指定每次分配的塊的大小
for (int i = 0; i < 10000; ++i)
{
int * const t = p.malloc();
pool分配指定大小的內(nèi)存塊;需要的時候,pool會向系統(tǒng)
申請大塊內(nèi)存。
... // Do something with t; don't take the time to free() it
p.free( t );
// 釋放內(nèi)存塊,交還給pool,不是返回給系統(tǒng)。
}
pool的析構函數(shù)會釋放所有從系統(tǒng)申請到的內(nèi)存。
2. object_pool
與pool的區(qū)別在于:pool需要指定每次分配的塊的大小,object_pool需要指定
每次分配的對象的類型。
Example:
struct X { ... }; // has destructor with side-effects
void func()
{
boost::object_pool<X> p;
^
for (int i = 0; i < 10000; ++i)
{
X * const t = p.malloc();
注意;X的構造函數(shù)不會被調(diào)用,僅僅是分配大小為sizeof(X)
的內(nèi)存塊。如果需要調(diào)用構造函數(shù)(像new一樣),應該調(diào)用
construct。比如:
X * const t = p.construct();
...
}
}
3. singleton_pool
與pool用法一樣。不同的是:可以定義多個pool類型的object,都是分配同樣
大小的內(nèi)存塊;singleton_pool提供靜態(tài)成員方法分配內(nèi)存,不用定義object。
Example:
struct MyPoolTag { };
typedef boost::singleton_pool<MyPoolTag, sizeof(int)> my_pool;
void func()
{
for (int i = 0; i < 10000; ++i)
{
int * const t = my_pool::malloc();
// ^^^^^^^^^
// 和pool不一樣。
...
}
my_pool::purge_memory();
// 釋放my_pool申請的內(nèi)存。
}
4. pool_alloc
基于singleton_pool實現(xiàn),提供allocator(用于STL等)。
Example:
void func()
{
std::vector<int, boost::pool_allocator<int> > v;
for (int i = 0; i < 10000; ++i)
v.push_back(13);
}
需要的話,必須自己顯式地調(diào)用
boost::singleton_pool<boost::pool_allocator_tag, sizeof(int)>::release_memory()
把allocator分配的內(nèi)存返回系統(tǒng)。
實現(xiàn)原理
pool每次向系統(tǒng)申請一大塊內(nèi)存,然后分成同樣大小的多個小塊,
形成鏈表連接起來。每次分配的時候,從鏈表中取出頭上一塊,提
供給用戶。鏈表為空的時候,pool繼續(xù)向系統(tǒng)申請大塊內(nèi)存。
一個小問題:在pool的實現(xiàn)中,在申請到大塊內(nèi)存后,馬上把它分
成小塊形成鏈表。這個過程開銷比較大。即你需要分配一小塊內(nèi)存
時,卻需要生成一個大的鏈表。用如下代碼測試:
boost::pool<> mem_pool(16);
for(i = 0; i < NPASS; i++) {
period = clock();
for(n = 0; n < NITEM; n++) {
array_ptr[n] = (int *)mem_pool.malloc();
}
for(n = 0; n < NITEM; n++) {
mem_pool.free(array_ptr[n]);
}
period = clock() - period;
printf("pool<> : period = %5d ms ", period);
}
可以發(fā)現(xiàn),第一遍花的時間明顯多于后面的。
而且在pool的使用過程中如果不是恰好把鏈表中所有的小塊都用上
的話,在鏈表中最后的一些小塊會始終用不上。把這些小塊加入鏈
表是多余的。雖然這個開銷可能很小:)
轉(zhuǎn)自:http://blog.csdn.net/xushiweizh/archive/2006/11/21/1400426.aspx