openGauss数据库源码解析(三)| 公共组件源码解析(5)

3.5 内存管理

数据库在运行过程中涉及许多对象,这些对象具有不同的生命周期,有些处理需要频繁分配内存。如一个SQL语句,在解析时需要对词法单元和语法单元分配内存,在执行过程中需要对执行状态分配内存。在事务结束时,如果不是PREPARE语句,那么SQL语句的执行计划内存和执行过程的状态内存都需要释放。如果是PREPARE语句,那么执行计划需要保存到缓冲池中,执行过程的状态内存释放即可。为了保证内存分配的高效和避免内存泄漏,openGauss设计开发了自己的内存管理,代码实现在“openGauss-serversrccommonbackendutilsmmgr”目录。

openGauss在内存管理上采用了上下文的概念,即具有同样生命周期或者属于同一个上下文语义的内存放到一个MemoryContext管理,MemoryContext的结构代码如下(结构成员参照注释):

typedef struct MemoryContextData { NodeTag type; /* 上下文类别*/ MemoryContextMethods* methods; /* 虛函数表*/ MemoryContext parent; /* 父上下文。顶级上下文为 NULL*/ MemoryContext firstchild; /* 子上下文的链表头*/ MemoryContext prevchild; /* 前向子上下文 */ MemoryContext nextchild; /* 后向子上下文 */ char* name; /* 上下文名称,方便调试 */ pthread_rwlock_t lock; /*上下文共享时的并发控制锁 */ bool is_shared; /* 上下文是否在多个线程共享 */ bool isReset; /* isReset为true时,表示复位后没有内存空间用于分配*/ int level; /* 上下文层次级别*/ uint64 session_id; /* 上下文属于的会话ID */ ThreadId thread_id; /* 上下文属于的线程ID */ } MemoryContextData;