C++ STL 用の空間コンフィギュレーター

スペース コンフィギュレーターの概要

C++ のメモリ構成操作と解放操作は次のようなものであることがわかっています。

class Foo {
    
    ...};
Foo* pf = new Foo;	//配置内存,然后构造对象
delete pf;			//将对象析构,然后释放内存

new には、次の 2 つの操作フェーズが含まれます。 1. 演算子 new を呼び出してメモリを構成します。2. コンストラクターを呼び出してオブジェクトのコンテンツを構築します。

delete には、次の 2 つのフェーズの操作も含まれます。 1. デストラクターを呼び出します。2. オペレータ delete を呼び出してメモリを解放します。

分業を正確に行うために、STL はこれら 2 つの操作フェーズを分離します。メンバー関数 assign() はメモリ構成操作を担当し、 dealcate() はメモリ解放を担当し、construct() はオブジェクト構築を担当し、 destroy() はオブジェクト破棄を担当します

メモリ割り当てのプロセスでは、考慮すべき問題がいくつかあります。

  1. メモリの小さなブロックによって引き起こされるメモリの断片化の問題。
  2. メモリの小さなブロックを頻繁に適用および解放することによって発生するパフォーマンスの問題。

これらの問題を解決するために、SGI STL は 2 レベルのコンフィギュレータ、つまり第 1 レベル コンフィギュレータと第 2 レベル コンフィギュレータを設計しました。第 1 レベルのアロケーターは、malloc() と free() を直接使用します。第 2 レベルのコンフィギュレータは、状況に応じて異なる戦略を採用します。コンフィギュレーション ブロックが 128 バイトを超える場合は、「十分な大きさ」とみなされ、第 1 レベルのコンフィギュレータが呼び出されます。コンフィギュレーションブロックが 128 バイトより小さい場合は、 「小さすぎる」と判断される場合、追加の負担を軽減するために、複雑なメモリ プール管理方法が採用されています

第 1 レベルのコンフィギュレータ

ここに画像の説明を挿入
SGI の第 1 レベルのコンフィギュレータは、malloc()、free()、realloc() などの C 関数を使用して、実際のメモリの構成、解放、および再構成の操作を実行します。malloc または realloc が失敗した場合は、代わりに oom_malloc() および oom_realloc() を呼び出します。後者の 2 つは内部ループを持ち、メモリ不足の処理ルーチンを常に呼び出し、特定の呼び出し後に十分なメモリを獲得することを期待します。ただし、メモリ不足処理ルーチンがクライアントによって設定されていない場合は、 bad_alloc 例外が直接スローされるか、プログラムが終了します

注: メモリ不足処理ルーチンを設計するのはクライアントの責任であり、メモリ不足処理ルーチンを設定するのもクライアントの責任です。

第 2 レベルのコンフィギュレータ

セカンダリ コンフィギュレータは、メモリ プール + 空きリンク リストの形式を使用して、メモリの小さなブロックによって引き起こされる断片化を回避し、割り当ての効率を向上させ、使用率を向上させます。16 要素のフリー リンク リスト (free_list) によって管理され、各場所のメモリ サイズは 8、16、24、32、40、48、56、64、72、80 の 8 の倍数になります。 、88、96、104、112、120、128。

free_list のノード構造は次のとおりです。union を使用してメモリを節約し、各ノードが追加のポインターを必要としないようにします。

union obj
{
    
    
	union obj* free_list_link;
	char client_data[1];
}

メモリプールとフリーリンクリストの関係

メモリ プールと空きリンク リスト free_list の関係を次の図に示します。
ここに画像の説明を挿入

このうち、free_list の最初の要素は 8 バイトの領域を指しており、8 バイトの領域のうち 10 を割り当てました。free_list の最後の要素は 128 バイトのスペースを指しており、このスペースのうち 4 つを割り当てました。

free_list は、メモリ プール内の free_list に割り当てられた未使用のメモリを管理します。システムが free_list から 8 バイトのメモリを取得したい場合、free_list[0] から先頭の最初の要素を直接ポップし、その後、トップバック。

セカンダリ コンフィギュレータのメモリ割り当て

主に次の 4 つの状況があります。

  1. free_list リストに空きメモリがあります。3 バイトのメモリを申請する場合、必要なスペース サイズは 8 の倍数に増加し、free_list に移動して対応するリンク リストを見つけます。free_list[i] が空でない場合は、最初の要素を返してから移動します。ヘッドポインタを後方にシフトします。
  2. free_list リストには空きはありませんが、メモリプールは空ではありません。まず、メモリ プール内のサイズが要求されたメモリよりも大きいかどうかを確認します。たとえば、20*8 メモリを適用し、十分な場合は対応するメモリを割り当て、そのうちの 1 つをユーザーに割り当て、残りをハングします。対応する free_listメモリ プールが十分な大きさではなく、少数のメモリ割り当てにのみ十分な場合は、これらを割り当てて、対応するデータを返します。1 つでも足りない場合は 3 番目のケースが実行されます。
  3. free_list リストにスペースがなく、メモリ プールが十分ではありません。malloc を呼び出してメモリを再割り当てします。割り当てるとき、2 倍のメモリを割り当て、対応するメモリを free_list の下にハングし、残りをメモリ プールに置きます。
  4. free_list リストにスペースがなく、メモリ プールが不十分で、malloc が失敗します。次に、ループ処理を行うか、例外をスローする第 1 レベルのスペース コンフィギュレーターを呼び出します。

ユーザーがセカンダリ スペース コンフィギュレータから要求したメモリが解放されると、セカンダリ スペース コンフィギュレータは、このメモリを直接解放するのではなく、回収されたメモリを対応する free_list に挿入しますプロセスは次のとおりです。
ここに画像の説明を挿入

要約する

第 1 レベルのコンフィギュレータの実装アイデアは、実際には、c の下で malloc、relloc、free をカプセル化し、それに C++ 例外を追加することです。メモリ不足の呼び出しが失敗した場合、メモリ不足の処理はユーザーが解決する必要がある問題であることを理解する必要があります。STL はそれに対処しませんが、メモリ不足がない場合には例外をスローします。メモリ処理メソッドを使用するか、呼び出しは失敗します。

第 2 レベルのコンフィギュレータは、メモリ プールとフリー リストを組み合わせた特に繊細なアイデアです。
フリー リストの各ノードは、メモリ サイズを 8 の倍数 (8、16、32...128 バイト) で維持します。まず、ユーザーは 128 バイト未満のメモリを申請し、第 2 レベルのコンフィギュレータ プログラムに入ります。ユーザーが初めて 32 バイトのメモリを申請すると、プログラムは 40 個の 32 バイト スペースを直接申請します。顧客と残りの 19 個をフリー リストに渡し、残りの 20 個をメモリ プールに渡します次に、2 回目のスペースを申請します。今回はユーザーが 64 バイトのスペースを必要とすると仮定します。まず、プログラムは 64 バイトの空きリンク リスト ノードに空きスペースがあるかどうかを確認します。空きスペースがある場合は、直接割り当てられます。そうでない場合はメモリ プールに移動され、メモリ プールのサイズによって 64 バイトのノードがいくつ割り当てられるかを確認し、完全に満たされていれば 1 つがユーザーに割り当てられ、残りの 19 個がユーザーに割り当てられます。残りの領域が十分でない場合は、64 バイト ノードを 20 個割り当て、最大数のメモリ プールをユーザーとフリー リストに可能な限り割り当てます。いずれも割り当てられない場合は、まずメモリ プールに残っている無駄な小さなメモリを対応する空きリンク リストに割り当て、その後 S_chunk_alloc を呼び出してメモリを適用します。メモリの適用が不足している場合は、未使用のメモリが存在するかどうかを確認します。フリーリンクリストの大きいもの メモリブロックがあればメモリプールに与えられ、再帰的に S_chunk_alloc が呼び出されます フリーリストがなければ第 1 レベルのアダプタに渡されます (なぜならメモリ不足に対処する方法があります)。メモリが十分な場合は、メモリ プールを補うために要求されたメモリが取得されます。上記の操作を繰り返し、1 つをクライアントに、残りの 19 をフリー リストに、残りをメモリ プールに与えます。

おすすめ

転載: blog.csdn.net/TABE_/article/details/126527159