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

        话说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()方法。先上图,然后分块解读处理流程。

 


PostgreSQL的内存管理机制三:AllocSet/MemoryContext实例删除和内存回收_第1张图片

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实例删除和内存回收_第2张图片

 

 

就到这儿吧。


你可能感兴趣的:(工作,delete,PostgreSQL,图形)