| Документация по PostgreSQL 9.4.1 | |||
|---|---|---|---|
| Пред. | Уровень выше | Глава 44. Интерфейс программирования сервера | След. |
44.3. Управление памятью
- Содержание
- SPI_palloc -- выделить память в верхнем контексте исполнителя
- SPI_repalloc -- поменять блок памяти в верхнем контексте исполнителя
- SPI_pfree -- освободить память в верхнем контексте исполнителя
- SPI_copytuple -- скопировать строку в верхнем контексте исполнителя
- SPI_returntuple -- подготовить строку для возврата в виде Datum
- SPI_modifytuple -- создать строку, заменяя отдельные поля в данной
- SPI_freetuple -- освободить строку, размещённую в верхнем контексте исполнителя
- SPI_freetuptable -- освободить набор строк, созданный
SPI_executeили подобной функцией- SPI_freeplan -- освободить ранее сохранённый подготовленный оператор
- SPI_palloc -- выделить память в верхнем контексте исполнителя
PostgreSQL выделяет память в контекстах памяти, и тем самым реализует удобный способ управления выделением памяти в различных местах, с разными сроками жизни выделенной памяти. При уничтожении контекста освобождается вся выделенная в нём память. Таким образом, нет необходимости контролировать каждый отдельный объект во избежание утечек памяти; вместо этого достаточно управлять только небольшим числом контекстов. Функция palloc и родственные ей освобождают память из "текущего" контекста.
SPI_connect создаёт новый контекст памяти и делает его текущим. SPI_finish восстанавливает контекст, который был текущим до этого, и уничтожает контекст, созданный функцией SPI_connect. Эти действия обеспечивают при выходе из вашей процедуры освобождение временной памяти, выделенной внутри процедуры, во избежание утечки памяти.
Однако, если ваша процедура должна вернуть объект в выделенной памяти (как значение типа, передаваемого по ссылке), эту память нельзя выделять через palloc, как минимум пока установлено подключение к SPI. Если вы попытаетесь это сделать, объект будет освобождён при вызове SPI_finish и ваша процедура не будет работать надёжно. Для решения этой проблемы выделяйте память для возвращаемого объекта, используя SPI_palloc. SPI_palloc выделяет память в "верхнем контексте исполнителя", то есть, в контексте памяти, который был текущим при вызове SPI_connect; именно этот контекст подходит для значения, возвращаемого из процедуры.
Если SPI_palloc вызывается, когда процедура не подключена к SPI, она действует как обычная функция palloc. До подключения процедуры к менеджеру SPI текущим контекстом является верхний контекст исполнителя, так что все операции выделения памяти, выполняемые процедурой через palloc или служебные функции SPI, производятся в этом контексте.
Когда вызывается SPI_connect, текущим контекстом становится частный контекст процедуры, создаваемый в SPI_connect. Все операции выделения памяти, выполняемые функциями palloc, repalloc или служебными функциями SPI (за исключением SPI_copytuple, SPI_returntuple, SPI_modifytuple и SPI_palloc), производятся в этом контексте. Когда процедура отключается от менеджера SPI (выполняя SPI_finish), текущим контекстом снова становится верхний контекст исполнителя, а вся память, выделенная в контексте процедуры, освобождается, так что использовать её дальше нельзя.
Все функции, описанные в этом разделе, могут использоваться и в подключённых, и в неподключённых процедурах. В неподключённой процедуре они действуют как обычные низкоуровневые серверные функции (palloc и т. д.).
| Пред. | Начало | След. |
| SPI_getnspname | Уровень выше | SPI_palloc |