Python 垃圾回收机制与核心算法解析
在 Python 开发中,内存管理是性能优化的关键领域之一。与其他许多编程语言一样,Python 内置了自动垃圾回收(Garbage Collection, GC)机制,旨在帮助开发者自动释放不再使用的内存资源,避免内存泄漏。本文将深入分析 Python 中 GC 的核心算法及其工作原理。
一、引用计数(Reference Counting)
Python 的垃圾回收主要依赖于引用计数机制。在 Python 内部,每一个对象的核心结构体为 PyObject,其中包含一个引用计数器 ob_refcnt。
// object.h
struct _object {
Py_ssize_t ob_refcnt; /* 引用计数值 */
struct PyTypeObject *ob_type;
} PyObject;
1. 工作原理
当一个对象被创建时,其引用计数初始化为 1。每当有一个新的引用指向该对象(例如赋值操作 b = a,或将其放入列表、字典等容器),引用计数加 1。当引用该对象的变量被删除(如 del b)或超出作用域时,引用计数减 1。一旦引用计数降为 0,说明该对象已不可达,解释器会立即调用析构函数并释放其占用的内存。
2. 优缺点
优点:
- 高效实时:内存释放是即时的,无需等待后台线程。
- 易于实现:逻辑简单,开销相对较小。
- 生命周期明确:对象的生命周期与其引用紧密绑定。
缺点:
- 维护成本高:每次赋值或删除都需要更新计数,涉及原子操作以保证线程安全。
- 循环引用问题:无法处理两个或多个对象互相引用的情况。即使外部没有引用,这些对象内部的引用计数也不会归零,导致内存泄漏。
# 循环引用示例
a = [1, 2]
b = [2, 3]
a.append(b)
b.append(a)
del a
del b
# 此时 a 和 b 的引用计数均为 1,不会被立即回收
二、标记 - 清除算法(Mark-Sweep)
为了解决引用计数无法处理的循环引用问题,Python 引入了标记 - 清除算法作为辅助。
1. 算法原理
标记 - 清除算法通过追踪'根对象'(Root Objects)来构建可达性图。根对象包括全局变量、栈帧中的局部变量等。算法分为两个阶段:
- 标记(Mark):从根对象出发,遍历所有可达的对象,并将它们标记为'存活'。
- 清除(Sweep):扫描堆中的所有对象,未被标记的对象被视为不可达(Unreachable),将被清理并释放内存。


