45.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
创建的内存上下文。
这些动作确保在你的过程中的内存分配在过程退出时被回收,从而避免内存
泄露。
不过,如果你的过程需要返回一个在已分配内存中的对象(例如一个
传引用数据类型的值),你不能使用palloc
分配内存,或者说至少不能在连接到 SPI 时这样做。如果你试着这样
做,该对象会被SPI_finish
接触分配,那么
你的过程将无法可靠地工作。要解决这个问题,应使用
SPI_palloc
来为要返回的对象分配内存。
SPI_palloc
会在
"上层执行器上下文"中分配内存,也就是当
SPI_connect
被调用时的当前内存上下文,
它才是从你的过程中返回的值最适合的上下文。
如果在过程还没有连接到 SPI 时调用SPI_palloc
,
那么它的效用就和普通的palloc
相同。在一个
过程连接到 SPI 管理器之前,当前的内存上下文就是上层的执行器上下
文,所以所有由该过程通过palloc
或者 SPI
功能函数分配的内存都在这个上下文中。
当SPI_connect
被调用时,这个过程的私有
上下文(由SPI_connect
)会被作为当前上
下文。所有用palloc
、
repalloc
或者 SPI 功能函数(除了
SPI_copytuple
、
SPI_returntuple
、
SPI_modifytuple
和
SPI_palloc
)分配的内存都在这个上下文中。
当一个过程从 SPI 管理器断开连接时(通过
SPI_finish
),当前上下文被恢复到上层的
执行器上下文,并且在该过程的内存上下文中分配的内存都会被释放,
之后再不能被使用。
这一节中描述的所有函数都可以在已连接和未连接的过程中使用。在
一个未连接的过程中,它们的行为和底层的普通服务器函数(
palloc
等)相同。