引言
Python (CPython) 的内存管理策略与 Java 和 Go 有显著不同。它主要依赖引用计数 (Reference Counting) 来进行内存回收,辅以一个分代循环垃圾收集器 (Generational Cyclic GC) 来解决引用循环问题。
1. 引用计数 (Reference Counting)
这是 Python 内存管理的基石。每个 Python 对象都有一个
ob_refcnt 字段。
1.1 机制详解
- 增加引用:
当对象被赋值给变量、作为参数传递、加入容器时,
ob_refcnt加 1。 - 减少引用: 当变量离开作用域、被显式
del、从容器移除时,ob_refcnt减 1。 - 回收: 当
ob_refcnt降为 0 时,立即调用对象的析构函数 (__del__) 并释放内存。
伪代码 (C 语言风格):
#define Py_INCREF(op) (op->ob_refcnt++)
#define Py_DECREF(op) \
if (--(op->ob_refcnt) == 0) \
_Py_Dealloc(op)1.2 优缺点
- 优点:
- 实时性: 内存一旦不再使用立即回收,没有 STW 延迟。
- 简单: 实现逻辑直观。
- 缺点:
- 开销大: 每次变量赋值都要更新计数,原子操作(如果多线程)昂贵(Python 有 GIL,所以不需要原子操作,但仍有 CPU 开销)。
- 无法处理循环引用: 这是致命伤。
2. 循环引用与分代收集
为了解决 A -> B -> A
这种循环引用导致内存无法释放的问题,Python 引入了分代循环
GC。
2.1 容器对象 (Container Objects)
只有可能包含引用的对象(如 list, dict, class, tuple)才会被 GC 跟踪。简单的原子类型(如 int, str)不需要 GC 跟踪,因为它们不可能构成环。
2.2 循环检测算法
Python 使用一种基于引用计数副本的算法来检测环。
算法步骤 (伪代码):
def collect(generation):
# 1. 建立引用计数副本
# gc_refs = ob_refcnt
update_gc_refs()
# 2. 减去内部引用
# 遍历该代中所有对象,将其引用的对象的 gc_refs 减 1
# 这一步是为了消除"环"内部的引用影响
subtract_refs()
# 3. 标记可达对象
# 此时,如果 gc_refs > 0,说明有外部引用指向它,它是活跃的。
# 将其标记为 reachable,并递归标记其引用的对象。
move_unreachable_to_garbage()
# 4. 回收垃圾
# 剩下的 gc_refs == 0 的对象就是不可达的环
delete_garbage()2.3 分代假设 (Generational Hypothesis)
Python 将对象分为三代:0 代、1 代、2 代。 * 0 代: 新创建的对象。 * 1 代: 幸存过一次 0 代回收的对象。 * 2 代: 幸存过一次 1 代回收的对象。
触发机制: * 当 0 代对象数量减去回收数量达到阈值(默认 700),触发 0 代 GC。 * 当 0 代 GC 发生一定次数(默认 10 次),触发 1 代 GC。 * 以此类推。
3. 性能调优
Python 提供了 gc 模块来控制垃圾回收。
gc.disable(): 关闭自动 GC(引用计数仍在工作)。在对性能要求极高且确信无循环引用的场景下使用。gc.collect(): 手动触发 Full GC。gc.set_threshold(): 调整分代阈值。
总结
Python 的 GC 是 引用计数 (主) + 分代循环 GC (辅)。 * 引用计数保证了大多数对象的实时回收。 * 分代 GC 兜底解决循环引用,避免内存泄漏。
同主题继续阅读
把当前热点继续串成多页阅读,而不是停在单篇消费。
【Garbage Collection Series】GC 横向对比:Java vs Go vs Python vs Rust
多维度对比主流编程语言的内存管理策略,分析吞吐量、延迟与开发效率的权衡。
【Garbage Collection Series】Go 语言垃圾回收 (GC) 深度解析
深入分析 Go 语言的低延迟垃圾回收机制,包括三色标记法、混合写屏障以及 GC Pacing 调优。
【Garbage Collection Series】Java 垃圾回收机制详解
深入解析 Java 虚拟机 (JVM) 的垃圾回收算法,包括分代收集理论、CMS、G1 以及新一代的 ZGC 和 Shenandoah。
【Garbage Collection Series】现代 GC 技术前沿:低延迟与智能化
探索垃圾回收技术的最新进展,包括 ZGC 的染色指针、读屏障技术以及 AI 驱动的参数调优。