CPython 引用计数和垃圾回收内部机制

主要观点:CPython 的运行时提供管理程序执行期间内存的关键服务,其使用引用计数和分代垃圾收集器(GC)进行自动内存管理,本文重点介绍 GC 实现。
关键信息

  • 内存布局中对象头部存储引用计数,包含ob_refcnt(对象引用计数)和ob_type(指向PyTypeObject的指针)。
  • 引用计数简单直接,但在循环引用时失效,CPython 用 GC 处理。
  • CPython 实现分代 GC,包括年轻代、老年代和永久代,新创建对象初始在年轻代,多次存活后晋升到老年代。
  • GC 周期通过eval_breaker标志调度,解释器在特定字节码指令时检查该标志,触发_Py_HandlePending处理异步事件包括 GC 事件,进而调用_Py_RunGC触发 GC 周期,_PyGC_Collect执行具体收集工作,gc_collect_region包含 GC 主要逻辑。
  • GC 的循环检测算法分三步,先初始化gc_refs,遍历内部引用递减gc_refs,最后将对象分为可达和不可达并清理不可达列表。
  • GIL 移除后,引用计数机制改为偏向引用计数以保证线程安全,GC 也有诸多变化,如从分代 GC 改为非分代 GC、使用 mimalloc 库跟踪对象、添加 GC 周期时的 stop-the-world 暂停等。
    重要细节
  • 各种结构体如gc_generationPyThreadState的定义及作用。
  • PyList_New函数创建新列表并进行 GC 跟踪的代码流程。
  • 循环引用检测算法在具体代码中的实现细节及示例。
  • 不同阶段 GC 对对象的处理及状态变化。
阅读 18
0 条评论