众所周知,计算机硬件资源由操作系统负责管理,内存资源也不例外。应用程序通过 系统调用 向操作系统申请内存,而 C 库函数则进一步将系统调用封装成通用的 内存分配器 ,并提供了 malloc 系列函数。
C 库函数实现的通用目的内存管理器是一个重要的分水岭,即内存管理层次中的 第 0 层 。此层之上是应用程序自己的内存管理,此层之下则是隐藏在冰山下方的操作系统部分。
操作系统内部是一个基于页表的虚拟内存管理器 (第 - 1 层),以 页 ( page ) 为单位管理内存,CPU 内存管理单元 ( MMU ) 在这个过程中发挥重要作用。虚拟内存管理器下方则是底层存储设备 ( 第 - 2 层),直接管理物理内存以及磁盘等二级存储设备。
绿色部分则是 Python 自己的内存管理,分为 3 层:
第 1 层,是一个内存分配器,接管一切内存分配,内部是本文的主角 —— 内存池 ;
第 2 层,在第 1 层提供的统一 PyMem_XXXX 接口基础上,实现统一的对象内存分配 ( object.tp_alloc );
第 3 层,为特定对象服务,例如前面章节介绍的 float 空闲对象缓存池;
那么,Python 为什么不直接使用 malloc 系列函数,而是自己折腾一遍呢?原因主要是以下几点:
引入内存池,可化解对象频繁创建销毁带来的内存分配压力;
最大程度避免内存碎片化,提升内存利用效率;
malloc 有很多实现版本,不同实现性能千差万别;