無料スクリプト配布のPHP.TO   PHPの実用的なtips PHPマニュアル MySQLマニュアル Apacheマニュアル PostgreSQLマニュアル マニュアル検索    

44.3. メモリ管理

目次
SPI_palloc  -- 上位エクゼキュータコンテキスト内にメモリを割り当てる
SPI_repalloc  -- 上位エクゼキュータコンテキスト内にメモリを再割り当てる
SPI_pfree  -- 上位エクゼキュータコンテキスト内のメモリを解放する
SPI_copytuple  -- 上位エクゼキュータ内に行のコピーを作成する
SPI_returntuple  -- Datumとしてタプルを返す準備をする
SPI_modifytuple  -- 与えられた行の選択フィールドを置き換えた行を作成する
SPI_freetuple  -- 上位エクゼキュータコンテキスト内に割り当てられた行を解放する
SPI_freetuptable  --  SPI_execute や類似の関数によって生成された行セットを解放する
SPI_freeplan  -- 以前に保存した準備済み文を解放する

PostgreSQL は、 メモリコンテキスト 内にメモリを確保します。 これは、様々な場所で、必要な有効期間がそれぞれ異なるような割り当てを管理する便利な方法を提供します。 コンテキストを破壊することで、そこで割り当てられた全てのメモリを解放します。 したがって、メモリリークを防ぐための個々のオブジェクトの追跡を維持することは不要です。 その代わり、相対的に少量のコンテキストを管理する必要があります。 palloc と関連する関数は "現在の" コンテキストからメモリを確保します。

SPI_connect は新しくメモリコンテキストを作成し、それを現在のコンテキストとします。 SPI_finish は直前の現在のメモリコンテキストを戻し、 SPI_connect で作成されたコンテキストを破壊します。 これらの動作により、プロシージャ内で割り当てが行われる一時的なメモリがプロシージャの終了時に回収され、メモリリークが防止されることが保証されます。

しかし、(参照渡しのデータ型の値といった)プロシージャが割り当てられたメモリ内のオブジェクトを返す必要がある場合、少なくともSPIに接続していない期間は、 palloc を使用してメモリを確保することができません。 これを試行すると、そのオブジェクトは SPI_finish で解放されてしまい、プロシージャは正しく動作しないでしょう。 この問題を解決するには、 SPI_palloc を使用して、戻り値となるオブジェクト用のメモリを確保してください。 SPI_palloc "上位エクゼキュータコンテキスト" 内にメモリを割り当てます。 このメモリコンテキストは、 SPI_connect が呼び出された時点において現在のコンテキストだったものであり、プロシージャの戻り値用のコンテキストとしてまさに正しいものです。

プロシージャがSPIに未接続な状態で SPI_palloc が呼び出されると、普通の palloc と同じように動作します。 プロシージャがSPIマネージャに接続する前では、現在のメモリコンテキストは上位エクゼキュータコンテキストであり、そのため、プロシージャから palloc やSPIユーティリティ関数経由で割り当てられた全ては、このコンテキストで作成されます。

SPI_connect が呼び出されると、 SPI_connect によって作成されるプロシージャ固有のコンテキストが現在のコンテキストに作成されます。 palloc repalloc 、SPIユーティリティ関数( SPI_copytuple SPI_returntuple SPI_modifytuple SPI_palloc は除きます)によって作成される割り当ては全て、このコンテキスト内に作成されます。 プロシージャがSPIマネージャから( SPI_finish 経由で)切断した時、現在のコンテキストは上位エクゼキュータコンテキストに戻され、プロシージャメモリコンテキスト内で割り当てられたメモリは全て解放され、二度と使用することができません。

本節で説明する関数は全て、接続状態、未接続状態のどちらのプロシージャから使用することができます。 未接続のプロシージャでは、背後にある通常のサーバ関数( palloc など)と同様に動作します。


powered by SEO.CUG.NET