背景
原文链接:http://blog.csdn.net/ordeder/article/details/31768749
看了几个内存池的设计,如python,STL,基本上对内存的管理有两种结构:
1.block,即内存块,一般和内存页(pagesize)大小相关。
2.chunk,即内存分片,即在该内存块上分配要使用的内存空间。
例如python的pyIntObject中使用到的缓冲池的实现: http://blog.csdn.net/ordeder/article/details/25343633
对于内存池的管理,就涉及到了两种链表,
1.内存池的内存块链表
2.对于被使用后回收的内存分片,将被回放与内存分片的链表中。
内存池对于一个内存请求(k大小),将提供以2为倍数的略大于k的内存空间给用户。对于内存的分片,一般提供2^(i+2) (0<= i <=11)字节大小的不同内存分片。大于2^13B字节的内存的申请请求,内存池是不提供服务,而是直接通过系统的alloc进行分配的,当然这个内存的释放也不会被回收到内存分片链表(freelist)中。
PostGresql的内存上下文
每个内存池被他组织成一个内存上下文,而系统中多个内存池是通过一个树结构对这些内存上下文进行统一的组织和维护。下面是他的内存上下文的一些数据结构关系图(草图):
memoryContentData: 作为内存上下文的节点,多个节点构成系统的内存上下文树。
AllocSetContext: 作为内存池的基本数据结构,主要包括内存块链表:*block,和内存分片链表的数组Freelist[]
AllocBlockData:内存块结构,作为内存块的头部信息,其中的两个char*指针指向了该内存块的起始和终止的内存地址。aset作为该内存块从属于哪个AllocSetContext的标记。
AllocChunkData:内存分片结构(header),作为分片的头部信息,他的具体分片的内存空间紧接其后。头部信息中有有意思的要属于void * aset指针了,如果该分片为空闲(未被分派),那么aset指针将作为freelist所用,作为next指针指向下一个空闲的分片。否则,该内存分片被分配了(不为空闲)那么该分片必不在freelist[]的链表中,从而aset记录该分片属于哪个内存块(AllocBlockData)