深入解析 Python 垃圾回收机制:引用计数、标记清除与分代收集

Miles
Miles
发布时间:2026-10-12| 2人浏览过
原创

Python 的内存管理主要依赖引用计数机制,并辅以标记-清除和分代收集算法来解决循环引用问题。本文详细解析了 Python 垃圾回收的核心原理、数据结构及执行流程,帮助开发者深入理解内存管理机制。

Python 垃圾回收的核心机制

Python 主要采用引用计数(Reference Counting)作为垃圾回收的主要手段。在 Python 内部,每个对象(PyObject)都包含一个 ob_refcnt 字段,用于记录该对象被引用的次数。当引用计数归零时,解释器会立即回收该对象占用的内存。

#define PyObject_HEAD          \ 
  Py_ssize_t ob_refcnt;        \ 
  struct _typeobject *ob_type; 
typedef struct _object { 
  PyObject_HEAD 
} PyObject;

这种机制的优点是实时性强,无需等待特定触发条件。然而,引用计数无法解决循环引用(Circular Reference)的问题。当两个或多个对象相互引用,且不再被外部引用时,它们的引用计数永远不会归零,导致内存泄漏。

解决循环引用:标记-清除算法

为了解决容器类型(如 list、dictionary、class 实例等)可能产生的循环引用,Python 引入了标记-清除(Mark-and-Sweep)机制。所有容器对象内部都包含一个 PyGC_Head 结构,用于维护一个双向链表,跟踪所有可收集的对象。

typedef union _gc_head { 
  struct { 
    union _gc_head *gc_next; 
    union _gc_head *gc_prev; 
    Py_ssize_t gc_refs; 
  } gc; 
  long double dummy; /* force worst-case alignment */ 
} PyGC_Head;

标记-清除的执行流程

标记-清除算法分为“寻找”和“回收”两个阶段:

  1. 标记阶段(Mark):从根对象(Root Objects)开始,遍历所有容器类对象。可达的对象会被放入 reachable 链表,而不可达的对象(即循环引用部分)会被放入 unreachable 链表。
  2. 回收阶段(Sweep):遍历 unreachable 链表,回收其中的元素。

在标记过程中,gc.gc_refs 用于存储有效引用数。对于循环引用中的对象,其引用数会在 gc.gc_refs 中减 1。如果有效引用数为 0,则该对象可被回收。需要注意的是,不能直接修改 PyObject 的 refcnt,因为可能存在外部引用。如果外部引用对象不可回收,其引用的对象也不会被回收。

循环引用示例

以下代码展示了典型的循环引用场景:

a = [] 
b = [] 
a.append(b) 
b.append(a)

在此例中,a 和 b 相互引用,导致它们的引用计数不为零,但已无法从外部访问。标记-清除算法能够识别并回收这部分内存。

分代收集(Generational Collection)

虽然标记-清除解决了循环引用问题,但频繁调用 malloc 和 free 会影响性能。为此,Python 引入了分代收集机制,旨在提高对象池的效率。

分代策略

Python 将对象分为三代:0 代、1 代和 2 代。每代维护一个独立的链表,用于跟踪对象数量:

  • 0 代:最多维护 700 个对象。这是新创建对象存放的地方。
  • 1 代:最多维护 10 个对象。
  • 2 代:最多维护 10 个对象。

当某一代的对象数量超过限制时,Python 会触发标记-清除算法。经过多次回收后,0 代对象会被移至 1 代或 2 代。高代对象的检测回收频率低于 0 代,这基于一个假设:存活时间越长的对象,越可能是长期存在的对象,无需频繁检查。

分代收集的局限性

标记-清除和分代收集机制主要弥补了引用计数的缺点,特别是在处理容器循环引用方面发挥了关键作用。非容器类型(如 int、string)由于不存在循环引用,其引用为 0 时即被回收,不依赖分代机制。

总结

Python 的垃圾回收机制是一个多层次的系统。引用计数提供了基础的内存管理,标记-清除解决了循环引用问题,而分代收集则优化了性能。理解这些机制有助于开发者编写更高效、更稳定的 Python 代码。

以上就是 Python 垃圾回收机制的详细内容,更多关于 Python 内存管理的资料请关注本站其它相关文章!

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。