41.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によって作成されるプロシージャ固有のコンテキストが現在のコンテキストに作成されます。 pallocrepalloc、SPIユーティリティ関数(SPI_copytupleSPI_returntupleSPI_modifytupleSPI_pallocは除きます)によって作成される割り当ては全て、このコンテキスト内に作成されます。 プロシージャがSPIマネージャから(SPI_finish経由で)切断した時、現在のコンテキストは上位エクゼキュータコンテキストに戻され、プロシージャメモリコンテキスト内で割り当てられたメモリは全て解放され、二度と使用することができません。

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