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_copytuple, SPI_copytupledesc, SPI_copytupleintoslot, SPI_modifytuple, 和 SPI_palloc) 分配的記憶體都是在這個 環境中分配的.
如果一個過程與 SPI 管理器中斷(通過 SPI_finish),那麼目前 環境恢復為上層執行器環境,並且所有在該過程的記憶體環境 中分配的記憶體都釋放掉並且不能再次使用!
所有在本節內描述的函數都可以在已連結的和未連結的 過程中使用.在未連結的過程中,他們的行為和下層的 原始後端函數(palloc 等)相同.