Boost 開発ガイド-3.8pool

プール

メモリ プールは大きなメモリ空間を事前に割り当て、その中で特定のアルゴリズムを使用して、効率的かつ高速なカスタム メモリ割り当てを実現します。

boost.pool ライブラリは、単純な分離ストレージの考え方に基づいた高速かつコンパクトなメモリ プール ライブラリを実装しており、大量のオブジェクトを管理できるだけでなく、STL のメモリ アロケータとしても使用できます。これはある程度、小さなガベージ コレクション メカニズムに似ています。これは、多数の小さなオブジェクトを割り当て/解放する必要がある場合に非常に効率的であり、削除を考慮する必要がまったくありません。

プール ライブラリは、最も単純なプール、クラス インスタンスを割り当てるための object_pool、シングルトン メモリ プール用の singleton_pool、および標準ライブラリ用の pool_alloc の 4 つのコンポーネントで構成されます。

Pool は最も単純で使いやすいメモリ プール クラスであり、単純データ型 (POD) のメモリ ポインタを返すことができます。これは名前空間 boost にあります。プール コンポーネントを使用するには、ヘッダー ファイル <boost/pool/pool.hpp> を含める必要があります。

#include <boost/pool/pool.hpp>
using namespace boost;

プール コンポーネント自体には外部依存関係はありませんが、ヘッダー ファイル pool_fwd.hpp の singleton_pool は、boost.system ライブラリに間接的に依存します。不要なリンク エラーを回避するために、include ステートメントの前にマクロ BOOST_SYSTEM_NO_DEPRECATED を定義できます。

授業の概要

template <typename UserAllocator = default_user_allocator_new_delete>
class pool
{
    
    
public:
   explicit pool (size_type requested_size); //构造函数
   ~pool(); //析构函数
   size_type get_requested_size() const; //分配块大小
   void * malloc(); //分配内存
   void * ordered_malloc();
   void ordered_malloc(size_type n);
   bool is_from(void * chunk) const;
   void free (void * chunk); //归还内存
   void ordered_free(void * chunk);
   void free(void * chunks, size_type n);
   void ordered_free(void* chunks, size_type n);
   bool release_memory(); //释放内存
   bool purge_memory();
};

操作機能

プールのテンプレート タイプ パラメーター UserAllocator はユーザー定義のメモリ アロケーターで、特定のメモリ割り当てアルゴリズムを実装し、通常はデフォルトのdefault_user_allocator_new_delete を直接使用できます。これは内部で new[ ] と delete[ ] を使用してメモリを割り当てます。

pool のコンストラクターは、size_type 型の整数 requested_size を受け入れます。これは、プールによって毎回割り当てられるメモリ ブロックのサイズ (プールのメモリ プールのサイズではありません) を示します。この値は get_requested_size() で取得できます。プールは、必要に応じて使用済みメモリをシステムに自動的に申請したり、システムに返したりします。また、メモリが破棄されると、プールが保持しているすべてのメモリ ブロックを自動的に解放します。

メンバー関数 malloc() および requested_malloc() の動作は、c のグローバル関数 malloc() と非常によく似ています。この関数は、 void* ポインターを使用して、メモリー プールから割り当てられたメモリー ブロックを返します。サイズは、指定された requested_size です。コンストラクター内で。メモリ割り当てが失敗した場合、関数は 0 を返し、例外はスローされません。malloc() はメモリ プールからメモリ ブロックを任意に割り当てますが、ordered_malloc() は割り当て中に空きブロック リストをマージします。パラメータ付きの requested_malloc() 形式では、メモリの n ブロックを連続的に割り当てることもできます。割り当てられたメモリ ブロックは is_from() 関数を使用して、このメモリ プールから割り当てられているかどうかをテストできます。

malloc() に対応する関数のセットは free() で、以前に割り当てられたメモリ ブロックを手動で解放するために使用されます。これらのメモリ ブロックは、このメモリ プールから割り当てる必要があります (is_from(chunk) == true)。一般に、メモリ プールはメモリ割り当てを自動的に管理するため、メモリ プール内のスペースが不十分で割り当てられたメモリを解放する必要があると考えられる場合を除き、free() 関数を呼び出す必要はありません。

最後に、2 つのメンバー関数があります: release_memory() は、メモリ プールがすべての未割り当てメモリを解放しますが、割り当てられたメモリ ブロックは影響を受けません; purge_memory() は、メモリ ブロックがメモリ ブロックにあるかどうかに関係なく、プールに保持されているすべてのメモリを強制的に解放します。使用。実際、プールのデストラクターは purge_memory() と呼ばれます。通常の状況では、これら 2 つの関数をプログラマが手動で呼び出すべきではありません。

使用法

プールは使いやすく、C の malloc() のようにメモリを割り当てて、好きなように使用できます。特別な要件がない限り、割り当てられたメモリを解放するために free() を呼び出す必要はなく、プールがメモリを適切に管理します。例えば:

#define BOOST_SYSTEM_NO_DEPRECATED //避免链接boost.system库
int main()
{
    
    
	pool<> pl(sizeof(int)); //一个可分配int的内存池

	int* p = static_cast<int*>(pl.malloc()); //必须把void*转换成需要的类型
	assert(pl.is_from(p)); //测试是否分配出去

	pl.free(p); //释放内存池分配的内存块
	for (int i = 0; i < 100; ++i) //连续分配大量的内存
	{
    
    
		pl.ordered_malloc(10);
	}
} //内存池对象析构,所有分配的内存在这里都被释放

メモリの割り当てが失敗してもプールは例外をスローしないため、実際のコードでは null ポインタ エラーを防ぐために malloc() 関数によって返されたポインタをチェックする必要がありますが、通常、このような状況はめったに発生しません。

int *p = static_cast<int*>(p1.malloc());
if(p != nullptr)
  ...

pool<> についてはこれ以上の説明はありません。使い方は非常に簡単です。ただ 1 つだけ注意してください。これは、int、double などの一般的なデータ型のメモリ プールとしてのみ使用でき、適用することはできません。複雑なクラスとオブジェクトには、メモリを割り当てるだけでコンストラクターを呼び出さないため、今回は object_pool を使用する必要があります。

コード例

#define BOOST_SYSTEM_NO_DEPRECATED

#include <boost/pool/pool.hpp>
using namespace boost;

int main()
{
    
    
	pool<> pl(sizeof(int));

	int* p = static_cast<int*>(pl.malloc());
	assert(pl.is_from(p));

	pl.free(p);
	for (int i = 0; i < 100; ++i)
	{
    
    
		pl.ordered_malloc(10);
	}
	return 0;
}

おすすめ

転載: blog.csdn.net/qq_36314864/article/details/132061785