5

バックグラウンド

以前の質問により、 boost.poolboost.poolを詳細に調査することになりましたが、理解を深めるための補足的な質問があります。

前奏曲

このリファレンスでは、オブジェクト プール パターンについて次のように述べています。

オブジェクト プール パターンは、必要に応じてオブジェクトを割り当てて破棄するのではなく、すぐに使用できるように保持された初期化済みオブジェクトのセットを使用するソフトウェア作成設計パターンです。

私が知る限り、boost.pool(単純化された) は、主に のサイズに基づくメモリの割り当てと管理によってオブジェクト プール パターンを実装element_typeし、割り当てられたオブジェクトへの単純なポインターを返します。

element_type * malloc();
void free(element_type * p);

free簡単なブーストの例は、取得した要素を明示的に指定する必要がないことも示しています。

X * const t = p.malloc();
... // Do something with t; don't take the time to free() it.

質問

割り当てられたメモリがプール オブジェクトの破棄時に安全に解放されることは理解していますが、クライアントによって取得されたメモリのブロックが解放されてプールに戻され、インターフェイスが直接ポインタを返す場合に再利用可能であることをプールはどのように認識しますか?へelement_typeの呼び出しfree()はまだ必要ありませんか? つまり、メモリがまだ使用されていないことが確実でない場合、ブースト プールはどのようにしてこのメ​​モリを再利用できますか? そして、このメモリを再利用しない場合、これは wiki リファレンスで説明されているものと同じパターンと見なされますか?

4

2 に答える 2

8

メモリがまだ使用されていないことが確実でない場合、ブースト プールはどのようにこのメモリを再利用できますか?

できません。実際、そのメモリは再利用されません。プールが破棄されたときにリークがないことを保証するだけです。

そして、このメモリを再利用しない場合、これは wiki リファレンスで説明されているものと同じパターンと見なされますか?

リンクし た記事には次のように書かれています:オブジェクトプーリングは、クラスインスタンスの初期化コストが高い状況でパフォーマンスを大幅に向上させることができます

Boostプールの紹介から:プールは通常、小さなオブジェクトの割り当てと割り当て解除が多いときに使用されます。

いいえ、それらは同じパターンではありません。1 つは、構築にコストがかかるオブジェクト(スレッド、opengl リソースなど)を再利用するためのものです。もう 1 つは、多数の小さなオブジェクトを管理することを目的としており、標準のアロケーターよりも多くの制御が可能です。

ご指摘のとおり、プールの使用方法は 2 つあります。

  1. アロケーターとして、必要に応じて malloc()/free() を呼び出します。これは基本的なプール アロケータの使用法であり、メモリの断片化を減らすのに役立ちます
  2. 大量の一時オブジェクトを構築し、それらを削除する必要はありません。

2 番目のケースの例: 各ノードがポインターを使用して隣接ノードを格納するグラフ クラスがあるとします。次に、グラフのディープ コピーを作成する必要があります。一連の新しいノードを割り当て、古いノードから新しいノードにデータをコピーしますが、今度は近隣ポインターを初期化する必要があるため、古いポインターから新しいポインターへのマップが必要です。

std::map<node*,node*> old_ptr_to_new_ptr;

これは、プール アロケータが役立つ良い例です (プール アロケータを std コンテナーで使用する方法については詳しく説明しません)。大量の小さなオブジェクト (マップ ノード) がまとめて削除されます。

于 2013-04-06T13:50:07.367 に答える