SPI_execute 或类似函数创建的结果行集 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 时,会把该 C 函数的私有上下文 (由 SPI_connect 创建)设为当前上下文。所有通过 palloc、repalloc 或 SPI 实用函数分配的内存(本节另有说明的除外)都位于这个上下文中。当 C 函数通 过 SPI_finish 与 SPI 管理器断开连接时,当前上下文 会恢复为上层执行器上下文,而在该 C 函数内存上下文中分配的所有内存都会被 释放,之后就不能再使用。
如果您发现文档中有不正确的内容、与您使用特定功能的经验不符或需要进一步说明,请使用此表单来报告文档问题。