pg为了分配内存的时候,方便管理,不产生内存泄露,引入了MemoryContext,所有的内存全从MemoryContext 中进行分配,
所有的MemoryContext构成一棵树,树的根结点为 TopMemoryContext ,TopMemoryContext 只初始化一次,在数据据库启动过程中完成初始化
每次分配是从 CurrentMemoryContext ,上面进行分配的
主要用到了三个数据结构,具体在 utils/mmgr/aset.c 的文件中
typedef struct AllocSetContext { MemoryContextData header; /* Standard memory-context fields */ /* Info about storage allocated in this context: */ AllocBlock blocks; /* head of list of blocks in this set */ 是个链表 AllocChunk freelist[ALLOCSET_NUM_FREELISTS]; /* free chunk lists */ ,相同大小的构成一个纵向链表 bool isReset; /* T = no space alloced since last reset */ /* Allocation parameters for this context: */ Size initBlockSize; /* initial block size */ Size maxBlockSize; /* maximum block size */ Size nextBlockSize; /* next block size to allocate */ Size allocChunkLimit; /* effective chunk size limit */ AllocBlock keeper; /* if not NULL,keep this block over resets */ } AllocSetContext;
ypedef struct AllocBlockData { AllocSet aset; /* aset that owns this block */ AllocBlock next; /* next block in aset's blocks list */ char *freeptr; /* start of free space in this block */ char *endptr; /* end of space in this block */ } AllocBlockData;
typedef struct AllocChunkData { /* aset is the owning aset if allocated,or the freelist link if free */ void *aset; /* size is always the size of the usable space in the chunk */ Size size; #ifdef MEMORY_CONTEXT_CHECKING /* when debugging memory usage,also store actual requested size */ /* this is zero in a free chunk */ Size requested_size; #endif } AllocChunkData
typedef AllocSetContext *AllocSet;
typedef struct AllocBlockData *AllocBlock; /* forward reference */ typedef struct AllocChunkData *AllocChunk;
AllocSet 就是和MemoryContext 对应,每个 AllocSet 可以有多个 AllocBlock, 每个 AllocBlock 可以有多个 AllocChunk;AllocChunk 就是对应每次分配的内存,
AllocSet 中的所有 AllocBlock 存在 blocks 起始的链表中,释放的 AllocChunk 记录在 freelist 中,每个 freelist 是一个同样大小的 AllocChunk 链表的首接点
内存的分配和释放比较简单,就是在一大片内存中记录起始位置和大小, (编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|