1. 主题说明
AntDB的内存管理在开发时,使用了内存上下文机制来实现内存管理。本文就从AntDB的内存上下文机制出发,解析内存上下文的实现原理。
AntDB的代码中,涉及到内存的处理时,经常会看到下面这样的代码。
图1:切换内存上下文示例
以及图2所示的代码。
图2:在内存上下文中申请内存
这与平常开发C/C++程序的内存操作方式不太一样,多多少少会让人产生一些疑惑:
- 内存操作前后的MemoryContextSwitchTo是什么意思?
- 这个内存上下文为什么要切来切去的?什么时候需要切换?
- palloc函数只是调了一个函数指针,实际上由什么函数来实现的?
- 为什么经常只能看到内存申请操作,却看不到释放操作?内存申请到哪去了?不释放没问题吗?
接下来就为各位小伙伴慢慢解析一下这个内存上下文。
2. 内存上下文(MemoryContext)是什么
内存上下文是一种内存管理机制。通俗一点来说,内存上下文可以看作是内存块和操作该内存块的方法的一个集合。举个例子,有一种内存上下文叫MemoryContextA,如果用户切换到MemoryContextA的话,那么接下来的操作至少会遵循以下2个规则。
1) 申请的内存都是属于MemoryContextA,并且这些内存也会随着MemoryContextA的删除而被删除掉。
2) 操作内存(申请、释放、重分配等等)都是由MemoryContextA定义的方法来执行。
AntDB中存在很多内存上下文,在它们之间会建立如图3所示的树形关系。(同一层之间其实还有兄弟关系,本图为了突出树形的层级关系,未在图中标识出兄弟关系。)
图3:内存上下文树形关系
3. 为什么要引入内存上下文
C/C++程序的开发者对内存操作这一部分(特别是内存的申请/释放操作)肯定深有体会,其中内存泄漏的问题更是家常便饭。尤其是当我们使用传统的内存操作方式来开发一个大型的软件(系统)时,保证内存操作不会出问题是相当有挑战的,并且这也会造成更多的开发成本。
AntDB引入内存上下文机制后,可以使得我们不用在意每一处内存的申请/释放,也让内存管理工作变得更加清晰、方便、可靠。