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

前端之家收集整理的这篇文章主要介绍了PostgreSQL的内存管理机制三:AllocSet/MemoryContext实例删除和内存回收前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

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

typedef structMemoryContextMethods@H_404_3@

{@H_404_3@

void *(*alloc) (MemoryContext context,Sizesize);@H_404_3@

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

void (*free_p)(MemoryContext context,void *pointer);@H_404_3@

void *(*realloc) (MemoryContext context,void *pointer,Size size);@H_404_3@

void (*init)(MemoryContext context);@H_404_3@

void (*reset)(MemoryContext context);@H_404_3@

void (*delete) (MemoryContext context);@H_404_3@

Size (*get_chunk_space) (MemoryContext context,void *pointer);@H_404_3@

bool (*is_empty)(MemoryContext context);@H_404_3@

void (*stats)(MemoryContext context);@H_404_3@

#ifdef MEMORY_CONTEXT_CHECKING@H_404_3@

void (*check)(MemoryContext context);@H_404_3@

#endif@H_404_3@

} MemoryContextMethods;@H_404_3@

@H_404_3@

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

static void AllocSetDelete(MemoryContextcontext)@H_404_3@

void MemoryContextDelete(MemoryContext context)@H_404_3@

@H_404_3@

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


@H_404_3@

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

@H_404_3@

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

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

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

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

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

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


@H_404_3@

@H_404_3@

就到这儿吧。@H_404_3@ 原文链接:https://www.f2er.com/postgresql/196746.html

猜你在找的Postgre SQL相关文章