小布源码分析札记-04 :内存池技术

xiaobu 7天前 22

从PG后台进程的角度而言,它可以使用的内存分为共享内存(shared memory)和私有内存(private memory)。共享内存是一块静态的内存,在postmaster主进程启动阶段,还没有创建任何子进程之前,就通过mmap()系统调用来分配的。私有内存是后台进程在需要时,通过malloc()和free()申请和释放内存。本文讨论的内存池技术是针对私有内存的管理。

 

因为所有的私有内存都是通过malloc()来申请,最后通过free()释放。这两个函数都是系统调用,开销比较大。为了提高性能,自然PG在设计时就要寻找方法降低对malloc()和free()的调用频度。我们很快发现一个事实:malloc(10)和malloc(100000)在性能上没有啥区别。既然如此,我们何不一次性申请一大块内存,然后批发转零售,后续的内存申请,即可通过这个大蛋糕进行切割。这种切割只是指针的移动,根本不再涉及到系统调用,自然性能非常快。

以上就是内存池的基本思想:先通过malloc()申请一大块内存,然后切割成小块分给申请者。PG的内存池技术模拟了malloc()和free()的思想,给出了palloc()和pfree()两个函数,作用类似malloc()和free(),但是仅仅是在内存池内部倒腾。

当一个用户想使用内存池时,首先要创建一个内存池。然后调用palloc()从这个内存池中申请内存。不需要的内存可以使用pfree()释放到这个内存池中。最后这个内存池在不需要时,可以一次性销毁。

内存池还可以进一步组成树形结构,有父亲和儿孙。当删除一个父级内存池时,连带着把它的子孙内存池都删除掉。这种方式方便了内存池的管理,而且减少的内存泄露的可能性。PG的内核是用纯C编写的,C语言编写的程序,内存管理实属不易。PG内存池的技术很精致,大大减少了PG数据库实例内存泄露的可能性。

在本系列文章中,我会分析PG内存池的设计要点和细节。

最新回复 (0)
返回
发新帖