Skip to content

47.3. 内存管理#

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创建的上下文。这些操作确保在 C 函数退出时回收在 C 函数内部进行的瞬态内存分配,从而避免内存泄漏。

但是,如果 C 函数需要在已分配的内存中返回一个对象(例如按引用传递的数据类型的某个值),则不能使用palloc分配该内存,至少在连接到 SPI 时不能这样做。如果你尝试这样做,该对象将被SPI_finish释放,并且 C 函数将无法可靠地工作。要解决此问题,请使用SPI_palloc为返回对象分配内存。SPI_palloc在*“上层执行器上下文”*中分配内存,即在调用SPI_connect时为当前上下文的内存上下文,这正是从 C 函数返回的值的正确上下文。本节中描述的其他一些实用函数也会返回在上层执行器上下文中创建的对象。

当调用SPI_connect时,由SPI_connect创建的 C 函数的私有上下文将成为当前上下文。pallocrepalloc或 SPI 实用函数(本节中描述的情况除外)进行的所有分配都在此上下文中进行。当 C 函数从 SPI 管理器断开连接(通过SPI_finish)时,当前上下文将恢复为上层执行器上下文,并且在 C 函数内存上下文中进行的所有分配都将被释放,并且不能再使用。