Python 垃圾回收

CPython 引用计数 + 分代循环垃圾回收;理解循环引用与 gc 模块边界。

#type / concept #status / growing #tech / dev #resource / python #tech / lang / python

[!info] 关联笔记

Python 垃圾回收

这个概念为什么出现

两个对象互相引用时,引用计数无法归零。CPython 引入循环检测 GC。不懂会在排查“内存不降”时误判。

[!abstract] 一句话理解 多数对象靠引用计数即时回收;容器循环由分代 GC 检测;gc 模块可观察与调试,而非日常手动 free。

最小可观察示例

场景:构造循环引用并手动收集

# cycle_gc_demo.py
# 业务意图:演示循环引用与 gc.collect。
# 教学点:循环需要 GC;实现细节。

import gc


class Node:
    def __init__(self, name: str) -> None:
        self.name = name
        self.ref = None


def main() -> None:
    gc.collect()
    a, b = Node("a"), Node("b")
    a.ref, b.ref = b, a  # 循环
    del a, b
    n = gc.collect()
    print("collected unreachable cycles approx:", n)


if __name__ == "__main__":
    main()

建议运行:

python cycle_gc_demo.py

期望输出:collected unreachable cycles approx: 后为非负整数(具体数目因版本/其他对象而异)。

结合场景再看三个关注点

  1. del 名字不等于立刻解开循环。
  2. collect 返回收集统计相关值。
  3. 生产应避免不必要循环或使用弱引用。

核心概念与准确模型

  • 引用计数
  • 分代回收
  • 可调阈值(高级)
  • __del__ 与周期回收的复杂交互

边界情况与反直觉行为

  1. __del__ 复活对象
  2. 关闭 GC 仅极端场景
  3. 原生内存 不在 gc 管理

常见误区

[!warning] 常见误区:Python 没有 GC 只有计数 错误理解:单机制。
正确模型:计数 + 循环 GC(CPython)。

工程实践

  • 缓存用弱引用/显式上限
  • 排查泄漏:对象增长曲线
  • 不要在业务里频繁玩 gc 旋钮

本节总结

GC 是安全网。设计上仍应管理对象生命周期与缓存边界。

自测题

  1. 循环引用为何难倒纯引用计数?
  2. __del__ 为何危险?
参考答案
  1. 互相持有导致计数永不为 0。
  2. 与回收顺序/复活交互复杂,可拖住收集。

延伸阅读与资料来源

资料类型支撑内容
gc文档模块
Supporting Cyclic GCC-API实现向
创建于 2026/7/15 更新于 2026/7/15