1つのスペースコンフィギュレータ

ヘッダファイル <記憶>

STD :: 1.1割り当て、STD :: DEALLOCATE   による:: new演算子::演算子削除パッケージは実装

STD :: 1.2、構築STD :: Destoryはを    配置新しい実装とデストラクタを呼び出します

 

テンプレート<クラスT1、T2クラス>
インラインボイドh_construct(T1 * P、CONST T2&値)
{
	新しい(P)T1(値)。
}
テンプレート<クラスT>
インライン無効h_destroy(T *ポインタ)
{
	pointer->〜T();
}

 

1.3のstd ::のalloc

STLのを考慮に入れて、小さなメモリブロックの問題は、2つの問題がある:1)原因メモリの断片化

                     2)追加負担メモリのブロックを得るために、より小さな管理ブロックのための追加スペースの必要性、大きな追加の負担割合

二重レベルの設定、直接第一段構成のデザインのmalloc()free()を、第二段階は、構成面積がより大きい場合に、異なる戦略を用いた場合のように配置されている128バイト、第一段階のダイレクトコールが配置されています。アロケーションブロックがより少ない場合128バイト使用しながら、それを第一段構成の助けを借りずに、メモリ・プールを達成します。どのような第一段階の使用であるか、または配置された第2のステージは、マクロ定義を制御するように構成されています。SGIのSTLは、デフォルト設定では、第二段階です。

 

セカンドレベルの設定は維持 16 のGe 、フリーリストの各サイズの管理8,16,24 ... 120,128bytes の小ブロックを。

 

フリー・リスト、組合を介してリンクされたリストを構成する第1フィールドを管理ノードポインタの追加の負担を解決するために、次のように構成されているノード、第2のフィールド実際のブロックに

組合OBJ {
組合OBJ * free_list_link。
チャーたclient_data [1]。/ *クライアントはこれを見ています。* /
}。

クラス構造

クラスh_alloc
{
プライベート:
	列挙型{
		ALIGN = 8、//アライメント境界
		MAX_BYTES = 128、//上限
		NFREELISTS = MAX_BYTES / ALIGN //数
	}。

	フリーブロックリストノード構造に対応した労働組合のOBJ {//
		組合OBJ * free_list_link。
		チャーたclient_data [1]。/ *クライアントはこれを見ています。* /
	}。
	
プライベート:
	静的size_tのROUND_UP(size_tのバイト)//アライメント機能
	{
		リターン(((バイト)+(size_tの)ALIGN  -  1)&〜((size_tの)ALIGN  -  1));
	}

	// n番目のチェーンを用いた演算、nは0〜
	freeList_index size_tの静的(size_tのバイト)	
	{
		リターン(((バイト)+(size_tの)ALIGN  -  1)/(size_tの)ALIGN  -  1)。
	}

	//は、サイズnのオブジェクトを返し、およびサイズの他のブロックにN free_listに添加してもよいです
	静的な無効*リフィルは(size_t N);  

	サイズサイズのブロックのnobjsを収容することができます。//バルク・コンフィギュレーション・スペース
	静的のchar * chunk_alloc(size_tのサイズ、INT&nobjs)。

パブリック:
	静的ボイド*割り当ては(size_t N);
	静的な無効DEALLOCATE(void *型のp、size_tのN)。
	//静的な無効* REALLOCATE(void *型のp、size_tのold_sz、size_tのnew_sz)。

プライベート:
	静的OBJ *揮発性m_free_list [NFREELISTS]; // 16个フリーリスト
	静的のchar * m_start_free; //開始位置メモリプール、ch​​unk_allocの変化のみ()内
	静的のchar * m_end_free; //終了位置メモリプール、のみchunk_allocの変更()
	静的size_tののm_heap_size。
}。

char * h_alloc :: m_start_free = 0;
char * h_alloc :: m_end_free = 0;
size_tのh_alloc :: m_heap_size = 0;
型名h_alloc :: OBJ *揮発性h_alloc :: m_free_list [NFREELISTS]。

1)()関数を割り当てます

void *型h_alloc ::は(size_t n)を割り当てます
{
	OBJ *揮発性*のmy_free_list。
	OBJ *結果。
	//(MAX_BYTES> N)場合には最初の段階は、128バイトコンフィギュレータより大きい呼び出し
	{
		リターン(malloc関数(N))。
	}
	{
		//適した16自由なリストを見つけます
		my_free_list = m_free_list + freeList_index(N)
		結果= * my_free_list。
		もし(結果== 0)
		{
			// free_list利用できる、詰め替えfree_listを見つけられませんでした
			ボイド* R =リフィル(ROUND_UP(N))。
			Rを返します。
		}
		// free_listを調整
		* my_free_list = result-> free_list_link。
		結果を返します。
	}
}

2))(解放

空h_alloc :: DEALLOCATE(void *型のp、size_tのN)
{
	OBJ * Q =(OBJ *)P。
	OBJ *揮発性*のmy_free_list。
	IF(N> MAX_BYTES)
	{
		無料(Q);
		リターン;
	}
	対応free_listを//検索します
	my_free_list = m_free_list + freeList_index(N)

	// free_list、リカバリブロックを調整
	q->free_list_link = *my_free_list;
	*my_free_list = q;
}

3) refill()

填充自由链表用,缺省一次取20个新节点,具体看内存池大小

void* h_alloc::refill(size_t n)
{
	int nobjs = 20; //默认取20个节点
	char* chunck = chunk_alloc(n, nobjs);//从内存池申请内存
	if (nobjs == 1)
	{
		return chunck;   // 如果只申请到一个节点,不用调整free_list,直接返回
	}
	obj* volatile * m_free_list = m_free_list + freeList_index(n); //找到n号链表
	obj* result = (obj*)chunck; // 保存要返回的结果

	obj* next_obj = (obj*)(chunck + n);
	*m_free_list = next_obj; //链表第一个节点
	
	// 串联各个节点,第一个节点已经返回出去了
	obj* current_objs;
	for (int i = 1; ;i++)
	{
		current_objs = next_obj;

		if (nobjs - 1 == i)
		{
			current_objs->free_list_link = 0;
			break;
		}
		else
		{
			next_obj = (obj*)(next_obj + n);
			current_objs->free_list_link = next_obj;
		}
	}
	return result;
}

4) chunk_alloc()

从内存池取空间给refill函数,内存池不够,从堆空间获取内存给内存池

char*  h_alloc::chunk_alloc(size_t size, int& nobjs)
{
	size_t total_bytes = size * nobjs;
	size_t left_bytes = m_end_free - m_start_free;
	char* result;
	if(left_bytes > total_bytes) //内存池剩余空间满足需求量
	{
		result = m_start_free;
		m_start_free += total_bytes;
		return result;
	}
	else if (left_bytes > size) //内存池剩余空间不满足需求量,但是足够一个以上的区块
	{
		nobjs = left_bytes / size;
		total_bytes = nobjs * size;
		result = m_start_free;
		m_start_free += total_bytes;
		return result;
	}
	else //内存池大小不够一个区块
	{
		size_t bytes_to_get = 2 * total_bytes + round_up(m_heap_size >> 4);
		//size_t bytes_to_get = 2 * total_bytes;

		if (left_bytes > 0) //残余零头不浪费
		{
			obj* volatile * m_free_list = m_free_list + freeList_index(left_bytes); //找到n号链表
			((obj*)m_start_free)->free_list_link = *m_free_list;
			*m_free_list = (obj*)m_start_free;
		}
		//申请堆空间
		m_start_free = (char*)malloc (bytes_to_get);
		if (0 == m_start_free)
		{
			printf("chunk_alloc malloc failed\n");
			//申请失败处理,省略。。。
		}
		m_heap_size += bytes_to_get;
		m_end_free = m_start_free + bytes_to_get;
		//递归调用,修正nobjs
		return (chunk_alloc(size, nobjs));
	}
}

 

  

 

  

 

 

おすすめ

転載: www.cnblogs.com/ho966/p/11954974.html