pg的内存管理机制三:AllocSet/MemoryContext实例删除和内存回收

 

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

typedef struct MemoryContextMethods

{

     void    *(*alloc) (MemoryContext context, Size size);

     /* 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;

 

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

static void AllocSetDelete(MemoryContext context)

void MemoryContextDelete(MemoryContext context)

 

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

 


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

 

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

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

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

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

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

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

 

 

 

 

就到这儿吧。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值