39.3. 儲存器管理

Table of Contents
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 建立的環境。 這些動作確保在您的過程中分配的臨時內存在過程結尾的時候都被回收,避免內存洩漏。

不過,如果您的過程需要返回一個已分配的內存對像(比如一個傳遞引用的資料類型), 那麼您就不能用 palloc 分配返回的對象, 至少是不能在您已經和 SPI 連線上的時候。如果您試圖這麼做, 那麼該對像將在 SPI_finish 的時候被釋放, 因而您的過程就不能可靠地工作了!

要解決這個問題,使用 SPI_palloc 分配您的返回對象。 SPI_palloc"上層執行者環境"中分配空間,也就是調用 SPI_connect 時候的目前環境內存環境,該環境是從您的過程返回數值的正確環境。

如果還沒有連線到 SPI 的時候調用它,SPI_palloc 的行為和簡單的 palloc 一樣。 在一個過程和 SPI 管理器連線之前,目前的內存環境是上層執行者環境,因此所有該過程使用 palloc 或者 SPI 工具函數分配的空間都是在這個環境中分配的。

在調用 SPI_connect 之後,目前環境是該過程私有的, 由 SPI_connect 製作的環境。 所有透過 palloc/repalloc 或者 SPI 工具函數(除了 SPI_copytupleSPI_returntupleSPI_modifytuple, 和 SPI_palloc) 分配的內存都是在這個環境中分配的。 如果一個過程與 SPI 管理器斷開(透過 SPI_finish),那麼目前環境恢復為上層執行器環境, 並且所有在該過程的內存環境中分配的內存都釋放掉並且不能再次使用!

所有在本節內描述的函數都可以在已連線的和未連線的過程中使用。 在未連線的過程中,他們的行為和下層的原始後端函數(palloc 等)相同。