SPI_execute
や類似の関数によって生成された行セットを解放する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
など)と同様に動作します。