41.3. メモリ管理

目次
SPI_palloc -- 上位エグゼキュータコンテキスト内にメモリを割り当てます。
SPI_repalloc -- 上位エグゼキュータコンテキスト内にメモリを再割当します。
SPI_pfree -- 上位エグゼキュータコンテキスト内のメモリを解放します。
SPI_copytuple -- 上位エグゼキュータ内に行のコピーを作成します。
SPI_copytupledesc -- 上位エグゼキュータコンテキスト内に行記述子のコピーを作成します。
SPI_copytupleintoslot -- 上位エグゼキュータコンテキスト内に行と記述子のコピーを作成します。
SPI_modifytuple -- 与えられた行の選択フィールドを置き換えた行を作成します。
SPI_freetuple -- 上位エグゼキュータコンテキスト内に割り当てられた行を解放します。
SPI_freetuptable -- SPI_exec や類似の関数によって生成された行セットを解放します。
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_copytupledescSPI_copytupleintoslotSPI_modifytupleSPI_pallocは除きます)によって作成される割り当てはすべて、このコンテキスト内に作成されます。 プロシージャがSPIマネージャから(SPI_finish経由で)切断した時、現在のコンテキストは上位エグザキュータコンテキストに戻され、プロシージャメモリコンテキスト内で割り当てられたメモリはすべて解放され、2度と使用することができません。

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