46.3. Управление памятью #

SPI_palloc — выделить память в верхнем контексте исполнителя
SPI_repalloc — поменять блок памяти в верхнем контексте исполнителя
SPI_pfree — освободить память в верхнем контексте исполнителя
SPI_copytuple — скопировать строку в верхнем контексте исполнителя
SPI_returntuple — подготовить строку для возврата в виде Datum
SPI_modifytuple — создать строку, заменяя отдельные поля в данной
SPI_freetuple — освободить строку, размещённую в верхнем контексте исполнителя
SPI_freetuptable — освободить набор строк, созданный SPI_execute или подобной функцией
SPI_freeplan — освободить ранее сохранённый подготовленный оператор

Postgres Pro выделяет память в контекстах памяти и тем самым реализует удобный способ управления выделением памяти в различных местах, с разными сроками жизни выделенной памяти. При уничтожении контекста освобождается вся выделенная в нём память. Таким образом, нет необходимости контролировать каждый отдельный объект во избежание утечек памяти; вместо этого достаточно управлять только небольшим числом контекстов. Функция palloc и родственные ей освобождают память из «текущего» контекста.

SPI_connect создаёт новый контекст памяти и делает его текущим. SPI_finish восстанавливает контекст, который был текущим до этого, и уничтожает контекст, созданный функцией SPI_connect. Эти действия обеспечивают при выходе из вашей функции на C освобождение временной памяти, выделенной внутри этой функции, во избежание утечки памяти.

Однако если ваша функция на C должна вернуть объект в выделенной памяти (как значение типа, передаваемого по ссылке), эту память нельзя выделять через palloc, как минимум пока установлено подключение к SPI. Если вы попытаетесь это сделать, объект будет освобождён при вызове SPI_finish и ваша функция не будет работать надёжно. Для решения этой проблемы выделяйте память для возвращаемого объекта, используя SPI_palloc. SPI_palloc выделяет память в «верхнем контексте исполнителя», то есть, в контексте памяти, который был текущим при вызове SPI_connect; именно этот контекст подходит для значения, возвращаемого из функции на C. Некоторые из вспомогательных функций, описанных в этом разделе, также возвращают объекты, созданные в верхнем контексте исполнителя.

Когда вызывается SPI_connect, текущим контекстом становится частный контекст функции на C, создаваемый в SPI_connect. Все операции выделения памяти, выполняемые функциями palloc, repalloc или служебными функциями SPI (кроме описанных в этом разделе исключений), производятся в этом контексте. Когда функция на C отключается от менеджера SPI (выполняя SPI_finish), текущим контекстом снова становится верхний контекст исполнителя, а вся память, выделенная в контексте этой функции, освобождается, так что использовать её дальше нельзя.