这场分享将从实践角度带你深入了解 CPython 究竟是如何管理内存的:从 obj = SomeClass() 开始,一直到对象所占用的内存最终被重新利用,或释放并归还给操作系统。
我们将从基础开始:对象布局、引用计数,以及 CPython 的小对象分配器 pymalloc 如何通过 arena 和 pool 来分配内存,而不是每创建一个微小对象就调用一次 malloc。你将看到,在高频循环中创建大量整数、元组以及短生命周期对象时,CPython 实际上都做了些什么。
接下来,我们会梳理对象生命周期结束时发生的事情:当引用计数降为 0 后会发生什么?CPython 如何执行特定类型的释放逻辑以及可选的终结器?用户自定义的 __del__ 又是如何参与其中的?我们还会了解内存是如何被归还给分配器,或者被保存在 Free List 中以便快速复用,以及为什么从外部看起来,这种机制有时会像是发生了“内存泄漏”。
在后半部分,我们将重点关注优化机制以及内存分配器的替换。我们会介绍整数、元组、Frame 以及其他核心对象使用的 Free List:它们为什么存在、如何加速高频路径,以及为什么它们有时会让内存比你预期的更长时间保持占用。随后,我们会对比 pymalloc 和 mimalloc,了解它们在内存碎片、多线程行为等方面的差异,以及当你使用 mimalloc 运行 Python 时,实际发生了哪些变化。最后,我们还会通过简单的基准测试和类似 tracemalloc 的工具,看看如何衡量这些变化带来的实际影响。
通过这场分享,你将建立起一套清晰的 CPython 内存分配与释放流程模型,并直观理解 Free List 和其他内存分配器究竟在做什么。