PostgreSQL 8.2.3 中文文档
后退快退章41. 服务器编程接口快进前进

41.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 等)相同。


后退首页前进
SPI_getnspname上一级SPI_palloc