↑↓ 选择 ↵ 打开 ⌫ 改范围 完整检索页

pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。

受支持版本: 当前版本 (18) / 17 / 16 / 15 / 14
测试与开发版本: 19 / devel
不受支持的版本: 13 / 12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3 / 8.2 / 8.1 / 8.0 / 7.4 / 7.3 / 7.2 / 7.1
历史版本PostgreSQL 7.2 已于 2007 年 2 月结束社区维护,本页译文保留供仍在使用旧版本的读者参考。新系统请看当前版本。

21.3. 内存管理 #

SPI_copytuple — 在上层执行器上下文中创建元组的副本
SPI_copytupledesc — 在上层执行器上下文中创建元组描述符的副本
SPI_copytupleintoslot — 在上层执行器上下文中创建元组及其描述符的副本
SPI_modifytuple — 通过替换给定元组中的选定字段来创建一个元组
SPI_palloc — 在上层执行器上下文中分配内存
SPI_repalloc — 在上层执行器上下文中重新分配内存
SPI_pfree — 在上层执行器上下文中释放内存
SPI_freetuple — 释放先前在上层执行器上下文中分配的元组
SPI_freetuptable — 释放由 SPI_exec 或类似函数创建的元组集
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_copytupledesc、 SPI_copytupleintoslot、 SPI_modifytuple 和 SPI_palloc 除外)都位于这个上下文中。

当过程(通过 SPI_finish)与 SPI 管理器断开连接时, 当前上下文会恢复为上层执行器上下文,而在该过程内存上下文中分配的 所有内存都会被释放,不能再使用!

本节介绍的所有函数既可由已连接的过程使用,也可由未连接的过程使用。 在未连接的过程中,它们的行为与底层普通后端函数 (palloc 等)相同。

提交更正

译文有误、术语不当或页面显示问题,请到译文仓库 pgsty/pgdoc 报告译文问题。 英文原文本身的问题,请在当前版本的对应页面向上游反馈;上游不再修订已结束维护的版本。