0

0

Python垃圾回收源码解析_GC实现流程

冰川箭仙

冰川箭仙

发布时间:2026-03-12 02:31:12

|

737人浏览过

|

来源于php中文网

原创

python垃圾回收采用引用计数加三色标记思想的标记-清除分代机制,gc模块处理循环引用;对象分三代,按存活时间晋升,第0代最频繁回收;仅容器类型参与gc,流程含暂停计数、标记可达、清除未标记、重置链表;gc不替代引用计数,仅补充处理不可达循环引用。

python垃圾回收源码解析_gc实现流程

Python 的垃圾回收(GC)主要依靠引用计数 + 分代回收机制,其中 gc 模块负责管理循环引用——这是引用计数无法处理的部分。源码实现在 CPython 的 Modules/gcmodule.c 中,核心逻辑围绕“三色标记”思想的简化变体(实际为“标记-清除”,非并发 GC)展开,配合分代策略提升效率。

分代机制:按对象存活时间划分回收优先级

CPython 将对象分为三代(0、1、2),新创建对象进入第 0 代;每次第 n 代被回收后,幸存对象晋升到第 n+1 代(最高为第 2 代)。各代有独立计数器(gc_state->generation0/1/2),当某代对象数量超过阈值(如第 0 代默认 700),触发该代及更老代的回收。

  • 第 0 代最频繁触发,适合清理短期对象和常见循环引用(如局部作用域中构造的 list/dict 相互引用)
  • 第 2 代回收代价高,仅在长期运行或显式调用 gc.collect(2) 时才执行
  • 可通过 gc.get_threshold() 查看当前阈值,gc.set_threshold() 动态调整

标记-清除流程:识别并回收不可达循环引用

GC 不扫描所有 Python 对象,只处理“可被 GC 管理”的容器类型(如 listdictclass 实例等),它们在创建时被链入全局的 gc_list 双向链表。回收流程分四步:

  • 暂停引用计数更新:临时禁用部分对象的引用计数变更(避免并发修改干扰标记)
  • 标记可达对象:从根集(栈帧变量、全局变量、寄存器等)出发,递归遍历引用链,将所有可达对象打上“已标记”标志(使用对象头中的 gc_next 字段复用作标记位)
  • 清除未标记对象:遍历当前代的 gc_list,对未标记对象调用其 tp_dealloc,释放内存并触发 __del__(若定义)
  • 重置链表与计数器:将幸存对象移入下一代链表,更新各代计数器

关键数据结构与钩子支持

每个可 GC 对象需满足:头部包含 PyObject_VAR_HEAD + PyGC_Head(含 gc_next/gc_prev 指针)。CPython 在对象分配时(如 PyObject_GC_New)将其插入全局链表;销毁时(PyObject_GC_Del)移除。

VIVA
VIVA

一个免费的AI创意视觉设计平台

下载

立即学习Python免费学习笔记(深入)”;

  • gc.callbacks 是一个列表,可注册函数监听 GC 事件(如 gc.DEBUG_COLLECTABLE 输出可回收对象)
  • gc.get_objects(generation=0) 返回指定代中所有可 GC 对象,用于调试内存泄漏
  • 自定义类可通过设置 __slots__ = () 或继承 object(而非 dict)减少 GC 开销

与引用计数的协同关系

GC 并不替代引用计数,而是补充。绝大多数对象靠引用计数即时释放;GC 仅周期性介入处理“引用计数不为 0 但实际不可达”的循环引用。例如:

a = []  
b = []  
a.append(b)  
b.append(a)  # 此时 a、b 引用计数均为 2,删除 a/b 后仍为 1,需 GC 清理

注意:gc.disable() 会停用分代回收,但引用计数照常工作;此时循环引用将永久驻留内存,直到解释器退出。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
全局变量怎么定义
全局变量怎么定义

本专题整合了全局变量相关内容,阅读专题下面的文章了解更多详细内容。

93

2025.09.18

python 全局变量
python 全局变量

本专题整合了python中全局变量定义相关教程,阅读专题下面的文章了解更多详细内容。

106

2025.09.18

treenode的用法
treenode的用法

​在计算机编程领域,TreeNode是一种常见的数据结构,通常用于构建树形结构。在不同的编程语言中,TreeNode可能有不同的实现方式和用法,通常用于表示树的节点信息。更多关于treenode相关问题详情请看本专题下面的文章。php中文网欢迎大家前来学习。

548

2023.12.01

C++ 高效算法与数据结构
C++ 高效算法与数据结构

本专题讲解 C++ 中常用算法与数据结构的实现与优化,涵盖排序算法(快速排序、归并排序)、查找算法、图算法、动态规划、贪心算法等,并结合实际案例分析如何选择最优算法来提高程序效率。通过深入理解数据结构(链表、树、堆、哈希表等),帮助开发者提升 在复杂应用中的算法设计与性能优化能力。

30

2025.12.22

深入理解算法:高效算法与数据结构专题
深入理解算法:高效算法与数据结构专题

本专题专注于算法与数据结构的核心概念,适合想深入理解并提升编程能力的开发者。专题内容包括常见数据结构的实现与应用,如数组、链表、栈、队列、哈希表、树、图等;以及高效的排序算法、搜索算法、动态规划等经典算法。通过详细的讲解与复杂度分析,帮助开发者不仅能熟练运用这些基础知识,还能在实际编程中优化性能,提高代码的执行效率。本专题适合准备面试的开发者,也适合希望提高算法思维的编程爱好者。

44

2026.01.06

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

443

2023.07.18

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

605

2023.08.10

class在c语言中的意思
class在c语言中的意思

在C语言中,"class" 是一个关键字,用于定义一个类。想了解更多class的相关内容,可以阅读本专题下面的文章。

870

2024.01.03

C# ASP.NET Core微服务架构与API网关实践
C# ASP.NET Core微服务架构与API网关实践

本专题围绕 C# 在现代后端架构中的微服务实践展开,系统讲解基于 ASP.NET Core 构建可扩展服务体系的核心方法。内容涵盖服务拆分策略、RESTful API 设计、服务间通信、API 网关统一入口管理以及服务治理机制。通过真实项目案例,帮助开发者掌握构建高可用微服务系统的关键技术,提高系统的可扩展性与维护效率。

3

2026.03.11

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
最新Python教程 从入门到精通
最新Python教程 从入门到精通

共4课时 | 22.5万人学习

Django 教程
Django 教程

共28课时 | 4.9万人学习

SciPy 教程
SciPy 教程

共10课时 | 1.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号