PostgreSQL的内存管理机制三:AllocSetMemoryContext实例删除和内存回收

PostgreSQL的内存管理机制三:AllocSetMemoryContext实例删除和内存回收,第1张

概述        话说MemoryContextMethods结构里的函数实现了pg里AllocSet/MemoryContext的内存管理机制,定义见下面。 typedef structMemoryContextMethods {      void    *(*alloc) (MemoryContext context, Sizesize);      /* call this free_p i

话说MemoryContextMethods结构里的函数实现了pg里AllocSet/MemoryContext的内存管理机制,定义见下面。

typedef structMemoryContextMethods

{

voID *(*alloc) (MemoryContext context,Sizesize);

/* call this free_p in case someone #define's free() */

voID (*free_p)(MemoryContext context,voID *pointer);

voID *(*realloc) (MemoryContext context,voID *pointer,Size size);

voID (*init)(MemoryContext context);

voID (*reset)(MemoryContext context);

voID (*delete) (MemoryContext context);

Size (*get_chunk_space) (MemoryContext context,voID *pointer);

bool (*is_empty)(MemoryContext context);

voID (*stats)(MemoryContext context);

#ifdef MEMORY_CONTEXT_CHECKING

voID (*check)(MemoryContext context);

#endif

} MemoryContextMethods;

其中delete由AllocSet的静态函数AllocSetDelete()实现,具体签名在下面。它实现了AllocSet相关的内存删除机制。而MemoryContext即父类的内存删除由MemoryContextDelete()实现,签名在下面。这两个方法各自负责本类型中成员的内存删除工作,好像协作,完成了AllocSet/MemoryContext类型对象的删除和内存回收工作。

static voID AllocSetDelete(MemoryContextcontext)

voID MemoryContextDelete(MemoryContext context)

下面就写MemoryContextMethods.delete的实现者负责AllocSet实例删除的AllocSetDelete()这个函数以及相关的负责MemoryContext实例删除的MemoryContextDelete()方法。先上图,然后分块解读处理流程。


AllocSet/MemoryContext实例内存删除流程图

先说红色框吧,在红色框部分,MemoryContextDelete方法检查要删除的context是否有效,然后调用MemoryContextDeleteChildren方法,检查context的firstchild是否不为空,若不空就以firstchild指向的子context为参数调用MemoryContextDelete方法。这样就以MemoryContextDelete方法和MemoryContextDeleteChildren方法形成了递归调用,以删除当前的context及它的子context。

接着看黄色框,在前面形成递归调用的基础上,黄色框中主要是删除context及其子context的nextchild指向的子context。

再接着看蓝色框,主要是在前面形成递归调用的基础上,针对要删除的context及其子context调用AllocSetDelelte方法,处理context的aset和blocks成员,把aset置空,把AllocBlock列表blocks中的block使用过的内存空间逐个置0X7F,然后调free释放。这个blocks链表处理完后就到了绿色框中。

现在看绿色框和紫色框,在绿色框中,还是在前面形成递归调用的基础上,在绿色框中检查要删除的context的有效性,然后找到该context所在的AllockChunk类型实例chunk,根据该chunk找到其所属的context,把要删除的context和其所在的chunk所属的context一起作为参数调用AllocSetFree方法去释放要删除的context所占内存。AllocSetFree释放内存在《pg的内存管理机制二》中已经讨论过了,感兴趣可以去看一下。

这样就在以MemoryContextDelete方法和MemoryContextDeleteChildren方法形成的递归调用里逐个删除要删除的context及其firstchild和nextchild成员“链”上的context。具体看流程图吧。

结合图形看一个递归删除MemoryContext类型实例时的顺序的例子,图中一个圆圈代表一个MemoryContext类型实例,在左下方的是MemoryContext的firstshild成员,在右下方的是nextchild成员。图一是初始时的样子,现在要删除节点4,先顺着4的firstchild递归到其最终叶子节点6,将其按上面说的过程删除并释放空间,如图二。然后将节点4的nextchild节点7放到4的父节点3的nextchild子节点上,把节点3原来的nextchild子节点5放到节点7的nenxtchild子节点上,如图三。这时已经处理完了节点4的两个子节点,将节点4删除。


就到这儿吧。

总结

以上是内存溢出为你收集整理的PostgreSQL的内存管理机制三:AllocSet/MemoryContext实例删除和内存回收全部内容,希望文章能够帮你解决PostgreSQL的内存管理机制三:AllocSet/MemoryContext实例删除和内存回收所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/sjk/1179338.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-02
下一篇 2022-06-02

发表评论

登录后才能评论

评论列表(0条)

保存