当前位置: 首页 > news >正文

【从源码角度深度理解 CPython 的垃圾回收机制】:第2课循环引用:标记清除-分代回收

二. 循环引用的终结者:标记-清除(Mark-Sweep)

通过引用计数,我们已经处理了一部分引用个数为0的数据,但是还有一部分循环引用的对象没有被清理。这个如何处理呢?

为了解决循环引用问题,Python 引入了标记-清除(Mark-Sweep)算法,作为引用计数的补充。

2.1 标记-清除的基本原理

标记-清除算法分为两个阶段:

  1. 标记(Mark):从“根对象”(如全局变量、栈上的局部变量)出发,遍历所有可达对象,并给它们打上“存活”标记。
  2. 清除(Sweep):扫描所有被 GC 跟踪的对象,回收那些未被标记的对象(即不可达对象)。

2.2 什么是“根对象”?

“根对象”是程序可以直接访问的起点,包括:

  • 全局变量
  • 当前函数的局部变量
  • 调用栈中的参数
  • 内置模块、类、函数等

GC 从这些“根”出发,像洪水一样“淹没”所有能到达的对象。

2.3 GC 跟踪的对象

并非所有对象都会被 GC 扫描。只有那些可能参与循环引用的容器类对象才会被 GC 跟踪,例如:

  • listdictset
  • 自定义类的实例
  • tuple(如果包含可变对象)

intstrfloat 等原子类型不会被 GC 跟踪,因为它们无法形成循环引用。

你可以通过 gc.is_tracked(obj) 来检查一个对象是否被 GC 跟踪。

a = [1, 2, 3]        # list → 被 GC 跟踪 ✅
b = {'x': a}         # dict → 被 GC 跟踪 ✅
c = MyClass()        # 自定义实例 → 被 GC 跟踪 ✅
d = 42               # int → 不被 GC 跟踪 ❌
e = "hello"          # str → 通常不被跟踪(除非驻留)❌
f = (a, b)           # tuple 包含可变对象 → 被跟踪 ✅
g = (1, 2, 3)        # tuple 只含不可变 → 可能不被跟踪 ❌

举例

import gcprint(gc.is_tracked([1,2,3]))      # True
print(gc.is_tracked(42))           # False
print(gc.is_tracked("hello"))      # False (通常)
print(gc.is_tracked(( [1], )))     # True

2.4 细节追问

  1. 问题总结

问题

http://www.lryc.cn/news/615920.html

相关文章:

  • 机器学习线性归回实战(单因子和多音字分别建立预测房价模型)
  • 一个基于 Next.js 和 Puppeteer 的 Markdown 转图片服务,支持 Docker 部署和 API 集成
  • Node.js面试题及详细答案120题(01-15) -- 基础概念篇
  • python | numpy小记(十):理解 NumPy 中的 `np.random.multinomial`(进阶)
  • Stlink识别不到-安装驱动
  • 医防融合中心-智慧化慢病全程管理医疗AI系统开发(下)
  • 整数规划-分支定界
  • Docker Compose 部署高可用 MongoDB 副本集集群(含 Keepalived + HAProxy 负载均衡)
  • AI编程插件对比分析:CodeRider、GitHub Copilot及其他
  • 给AI装上“翻译聚光灯”:注意力机制的机器翻译革命
  • 【精彩回顾·成都】成都 User Group×柴火创客空间:开源硬件驱动 AI 与云的创新实践!
  • 打卡day34
  • openpnp - 顶部相机如果超过6.5米影响通讯质量,可以加USB3.0信号放大器延长线
  • Spark执行计划与UI分析
  • AutoCAD 2026 的主要功能
  • 变量详解:创建初始化与内存管理
  • lesson34:深入理解Python线程:从基础到实战优化
  • XGBoost算法在机器学习中的实现
  • Android Camera 打开和拍照APK源码
  • Android 开发问题:Invalid id; ID definitions must be of the form @+id/ name
  • Android 16 KB页面大小适配的权威技术方案总结
  • Ubuntu 安装 Kibana
  • 神经机器翻译(NMT)框架:编码器-解码器(Encoder-Decoder)结构详解
  • 支持selenium的chrome driver更新到139.0.7258.66
  • 去除Edge微软浏览器与Chrome谷歌浏览器顶部出现“此版本的Windows不再支持升级Windows 10”的烦人提示
  • Elasticsearch QueryDSL 教程
  • Linux操作系统从入门到实战(十八)在Linux里面怎么查看进程
  • 三、k8s 1.29 之 安装1网络 / ikuai路由器虚拟机安装
  • Linux810 shell 条件判断 文件工具 ifelse
  • JavaWeb(苍穹外卖)--学习笔记18(Apache POI)