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;

 

        其中realloc由静态函数AllocSetRealloc()实现,具体签名在下面。它实现了AllocSet/MemoryContext相关的内存再分配。AllocSetRealloc()方法返回按请求大小新分配的内存的指针。把新分配的内存加入到set中,把传进来的pointer相关的旧内存里的内容拷贝到新内存里,把旧内存释放掉。新分配的内存有可能是在原来的基础上再在后面加一部分,这样就不用拷贝旧内存内容和释放就内存了。

static void * AllocSetRealloc(MemoryContext context, void *pointer, Size size)

        在某个context里的chunk的内存不够用的时候,就调用MemoryContext的repalloc()方法,该方法再调用AllocSetRealloc()方法调整原来分配给AllocChunk类型实例chunk的大小。

        下面就写MemoryContextMethods. realloc的实现者AllocSetRealloc ()这个函数。先上图,然后分块解读处理流程。

 

PostgreSQL的内存管理机制四:AllocSet/MemoryContext的内存再分配_第1张图片

 AllocSetFree回收内存流程图

 

        先看红色框,根据传进来了要扩展内存的chunk和其所在的context,检查该chunk原来分配的空间oldsize和本次请求的空间size,如果原oldsize可以满足要求,就把该chunk的请求大小request_size置成size,返回该chunk。如果oldsize不能满足本次请求的大小size。就根据chunk原来分配的空间oldsize的是否大于AllocChunk的大小上限/8k判断,大于该上限就到黄色框,负责到蓝色框。

        接着看黄色框,根据该chunk找到其所在的block,以该block和根据请求的chunk大小size换算的AllocBlock的东西blksize调用realloc()方法分配内存,成功就返回对应chunk的指针,负责写日志报错“out of memory”

        再接着看蓝色框,检查chunk是否是其所在block里的最后一个AllocChunk,如果是,检查该block剩余的空间和该chunk的空间加起来是否满足全球的大小size,如果可以就在该block中开展这个chunk,然后返回该chunk的指针。负责就到了紫色框。

        最后看紫色框,调用AllocSetAlloc()方法(参见《pg的内存管理机制一》)在当前MemoryContext上分配空间新的空间该chunk,把chunk原来内存里的内容拷贝过来,调用AllocSetFree()释放chunk原来所占的内存。具体看流程图吧。

 


你可能感兴趣的:(delete,PostgreSQL,扩展)