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,Size size) 在某个context里的chunk的内存不够用的时候,就调用MemoryContext的repalloc()方法,该方法再调用AllocSetRealloc()方法调整原来分配给AllocChunk类型实例chunk的大小。 下面就写MemoryContextMethods. realloc的实现者AllocSetRealloc ()这个函数。先上图,然后分块解读处理流程。 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原来所占的内存。具体看流程图吧。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |