45.3. 内存管理

SPI_palloc — 在上层执行器上下文中分配内存
SPI_repalloc — 在上层执行器上下文中重分配内存
SPI_pfree — 在上层执行器上下文中释放内存
SPI_copytuple — 在上层执行器上下文中创建一行的拷贝
SPI_returntuple — 准备把一个元组返回为一个 Datum
SPI_modifytuple — 通过替换一个给定行的选定域来创建一行
SPI_freetuple — 释放一个在上层执行器上下文中分配的行
SPI_freetuptable — 释放一个由SPI_execute 或者类似函数创建的行集合
SPI_freeplan — 释放一个之前保存的预备语句

LightDB内存上下文中分配内存,内存上下文为管理 在多个不同位置、具有不同生存时间需要的分配提供了一种便捷的方法。 销毁一个上下文会释放所有在其中分配的内存。因此不必跟踪单个对象来 避免内存泄露,而是只需要管理数量相对较少的上下文即可。 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)会被作为当前上 下文。所有用pallocrepalloc或者 SPI 功能函数(除了这个小节中描述的例外)分配的内存都在这个上下文中。 当一个C函数从SPI管理器断开连接时(通过 SPI_finish),当前上下文被恢复到上层的 执行器上下文,并且在该过程的内存上下文中分配的内存都会被释放, 之后再不能被使用。