菜单

对象系统与内存管理

相关源文件

本页描述了 CPython 中核心对象系统和内存管理机制。它涵盖了 Python 对象在内存中的结构、类型系统、引用计数和垃圾回收。有关解释器状态和并发的详细信息,请参阅 运行时和线程管理

Python 对象模型

Python 的对象系统围绕所有对象共享的通用核心结构构建。该结构维护类型信息和引用计数等基本元数据。

来源:Include/object.h59-118 Include/cpython/object.h148-232 Objects/object.c43-63

PyObject 结构

每个 Python 对象都以一个包含关键元数据的通用头部开始。标准构建和无 GIL 的免费线程构建(禁用 GIL)的具体结构有所不同。

标准构建(带 GIL)

免费线程构建(禁用 GIL)

对于变长对象(如列表、元组),基本结构会增加一个额外的字段

来源:Include/object.h110-172 Include/internal/pycore_object.h99-173 Objects/object.c525-568

类型系统

Python 的类型系统定义了对象的行为。类型本身也是对象(是 type 元类的实例)。

PyTypeObject 结构包含大量定义对象行为的信息。

  1. 基本元数据:名称、大小、文档
  2. 常用操作的方法槽(tp_newtp_inittp_call 等)
  3. 方法表、成员定义和属性描述符
  4. 继承信息(基类和 MRO)
  5. 用于行为自定义的特殊标志

类型系统同时支持静态内置类型(如 intlist)和动态堆类型(通过类定义在运行时创建)。

来源:Include/cpython/object.h148-232 Objects/typeobject.c92-232

内存管理

Python 采用双管齐下的方法进行内存管理

  1. 引用计数:内存管理的主要机制
  2. 循环垃圾回收:处理引用循环的补充机制

引用计数

每个对象都维护一个指向它的引用计数。当计数达到零时,对象将被释放。

在免费线程构建中,引用计数更为复杂

  1. 线程本地引用计数(ob_ref_local):由拥有对象的线程管理
  2. 共享引用计数(ob_ref_shared):用于来自其他线程的引用
  3. 当本地计数达到零时,计数将被合并到共享计数中。

来源:Include/internal/pycore_object.h134-173 Objects/object.c332-520

垃圾回收

仅靠引用计数无法处理循环引用(当对象互相引用时)。垃圾回收器负责检测并打破这些循环。

垃圾回收器根据 GIL 是否启用而有不同的工作方式

  1. 标准模式(启用 GIL):使用分代收集器和对象链表
  2. 免费线程模式(禁用 GIL):在收集期间使用“停止世界”方法暂停所有线程

来源:Include/internal/pycore_gc.h16-81 Python/gc.c60-257 Python/gc_free_threading.c201-331

对象生命周期

对象创建

对象通过几种函数创建

  1. PyObject_New():创建一个特定类型的新对象
  2. PyObject_InitVar():创建一个变长对象
  3. _PyObject_New():低级分配函数

当对象被创建时

  1. 分配内存
  2. 引用计数初始化为 1
  3. 设置类型指针
  4. 可能执行特定于类型的初始化

来源:Objects/object.c525-568

对象终结与释放

当对象的引用计数达到零时

  1. 如果已定义(通过 PyObject_CallFinalizerFromDealloc()),可能会调用 tp_finalize()
  2. 调用 tp_dealloc() 来清理对象
  3. 释放内存

终结在对象被释放之前处理清理任务。这对于具有外部资源(如文件句柄)的对象尤为重要。

来源:Objects/object.c572-624

特殊内存管理功能

永生对象

一些对象被标记为“永生”,这意味着它们永远不会被释放。这些包括

  1. 单例对象,如 NoneTrueFalse
  2. 小整数(默认为 -5 到 257)
  3. 静态类型对象

对永生对象调用 Py_INCREF()Py_DECREF() 没有效果。

来源:Include/internal/pycore_object.h198-229

延迟引用计数

在免费线程构建中,某些对象使用“延迟引用计数”来减少争用

  1. 对象以大型共享引用计数(_Py_REF_DEFERRED)开始
  2. 这意味着对象在最后一个常规引用消失后不会立即释放
  3. 垃圾回收器负责回收这些对象

这种方法提高了多线程场景下的性能。

来源:Include/internal/pycore_object.h22-28 Python/gc_free_threading.c273-298

对象属性和字典

Python 对象通常在其字典中存储属性。实现方式因对象类型而异

字典实现

CPython 的字典使用

  1. 开放寻址和伪随机探测
  2. 紧凑表示以减少内存使用
  3. 有序插入(保留键插入顺序)
  4. 属性字典的分表架构(在多个实例之间共享键)

来源:Objects/dictobject.c1-106 Include/internal/pycore_dict.h50-106

免费线程模式(禁用 GIL)

Python 3.13 引入了在没有全局解释器锁 (GIL) 的情况下运行的实验性支持。这需要对内存管理系统进行重大更改

  1. 每个线程和共享引用计数
  2. 对象所有权模型(对象被线程“拥有”)
  3. 某些对象的延迟引用计数
  4. 用于常见操作的无锁数据结构
  5. 修改后的垃圾回收算法

此模式允许 Python 更好地利用多核 CPU,但会带来一定的性能开销,尤其是在单线程代码中。

来源:Doc/whatsnew/3.13.rst103-115 Include/object.h183-258 Python/gc_free_threading.c34-76

稳定 ABI 考虑因素

Python 维护着一个稳定的 ABI(二进制接口),以保证跨 Python 版本的二进制兼容性。对象系统中包含在稳定 ABI 中的关键组件包括

  1. 核心对象函数(Py_INCREFPy_DECREF 等)
  2. 对象创建和检查函数
  3. 类型检查和转换函数
  4. 部分结构定义,仅公开必需的成员

稳定的 ABI 函数在代码中标明,并在 Misc/stable_abi.toml 中明确列出。

来源: Misc/stable_abi.toml16-63 PC/python3dll.c16-48 Doc/data/stable_abi.dat1-43


本页面提供了 CPython 对象系统和内存管理的概述。理解这些基础知识对于深入研究 Python 内部和编写高效的扩展至关重要。