Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >垃圾回收机制 | Python

垃圾回收机制 | Python

作者头像
阿珍
发布于 2025-05-14 09:47:41
发布于 2025-05-14 09:47:41
380
举报

python采用的是引用计数机制为主,分代回收(隔代回收)标记-清除两种机制为辅的策略。

引用计数机制

正是因为有引用,对象才会在内存中存在。

引用计数是一种非常高效的内存管理手段,当一个pyhton对象被引用时其引用计数增加1,当其不再被引用时引用计数减1,当引用计数等于0的时候,对象就被删除了。

优点

  1. 实现简单。
  2. 垃圾回收的实时性。一旦没有引用,内存被直接释放;分摊处理内存回收的时间。

缺点

  1. 使用额外内存维护引用计数
  2. 循环引用导致内存泄漏

导致对象的引用计数+1的情况

  1. 创建对象
  2. 对象被引用
  3. 对象作为参数,传入到函数中
  4. 对象作为容器的元素,如l = [a, a]

导致对象的引用计数-1的情况

  1. 引用被重新赋值
  2. 引用被del,del删除的是引用,而不是对象
  3. 超过作用域
  4. 元素所在的容器被销毁

分代回收

从理论上说,对象的创建数目==释放数目。但是如果存在循环引用的话,肯定是创建>释放数量,当创建数与释放数量的差值达到规定的阈值的时候,当当当当~分代回收机制就登场啦。

Python根据对象的存活时间将内存划分为年轻代、中年代和老年代,分别用0,1,2表示。

越年轻的对象越容易死掉,老的对象通常会存活更久。 新生的对象被放入0代,如果该对象在第0代的一次gc垃圾回收中活了下来,那么它就被放到第1代里面(它就升级了)。如果第1代里面的对象在第1代的一次gc垃圾回收中活了下来,它就被放到第2代里面。

分代回收算法

  1. 从上一次第0代gc后,如果分配对象的个数减去释放对象的个数大于threshold0,那么就会对第0代中的对象进行gc垃圾回收检查。
  2. 从上一次第1代gc后,如果第0代被gc垃圾回收的次数大于threshold1,那么就会对第1代中的对象进行gc垃圾回收检查。
  3. 从上一次第2代gc后,如果第1代被gc垃圾回收的次数大于threshold2,那么就会对第2代中的对象进行gc垃圾回收检查。

gc.set_threshold(threshold0[, threshold1[, threshold2]) 设置各代执行垃圾回收的阈值。

有三种情况会触发垃圾回收:

  1. 调用gc.collect(),显式进行垃圾回收;
  2. 当gc模块的计数器达到阈值的时候;
  3. 程序退出的时候。

分代回收是建立在标记清除技术基础之上。分代回收同样作为Python的辅助垃圾收集技术处理那些容器对象,因为对于字符串、数值对象是不可能造成循环引用问题。

标记清除技术

标记清除用来解决循环引用产生的问题,循环引用只有在容器对象才会产生,比如字典,元祖,列表等。

在标记清除算法中有两个链表,root链表和unreachable链表。unreachable链表中的对象会被回收。

为什么设置两个链?

unreachable链表中可能存在被root链表中的对象、直接或间接引用的对象,这些对象是不能被回收的,一旦在标记的过程中,发现这样的对象,就将其从unreachable链表中移到root链表中;当完成标记后,unreachable链表中剩下的所有对象就是名副其实的垃圾对象了,接下来的垃圾回收只需限制在unreachable链表中即可。

Python使用一个双向链表将这些容器对象组织起来。不过,这种简单粗暴的标记清除算法也有明显的缺点:清除非活动的对象前它必须顺序扫描整个堆内存,哪怕只剩下小部分活动对象也要扫描所有对象。

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
一文读懂Python垃圾回收机制【收藏版】
得益于Python的自动垃圾回收机制,在Python中创建对象时无须手动释放。这对开发者非常友好,让开发者无须关注低层内存管理。但如果对其垃圾回收机制不了解,很多时候写出的Python代码会非常低效。
superhua
2022/07/11
4.4K0
一文读懂Python垃圾回收机制【收藏版】
Python 进阶:浅析「垃圾回收机制」
花下猫语:近半个月里,我连续写了两篇关于 Python 中内存的话题,所关注的点都比较微小,猎奇性质比实用性质大。作为对照,今天要分享一篇长文,是跟内存相关的垃圾回收话题,一起学习进步吧! 作者:二两
Python猫
2019/09/19
2.2K0
Python 进阶:浅析「垃圾回收机制」
python进阶(7)垃圾回收机制
现在的高级语言如java,c#等,都采用了垃圾回收机制,而不再像c,c++里,需要用户自己管理内存。自己管理内存及其自由,可以任意申请内存,但这如同一把双刃剑,可能会造成内存泄漏,空指针等bug。 python中也同java一样采用了垃圾回收机制,不过不一样的是:python采用的是引用计数机制为主,标记清除和分代回收两种机制为辅的策略
全栈程序员站长
2022/09/19
7590
剖析 Python 面试知识点(二)- 内存管理和垃圾回收机制
Python 中一切皆对象,对象又可以分为可变对象和不可变对象。二者可以通过原地修改,如果修改后地址不变,则是可变对象,否则为不可变对象,地址信息可以通过id()进行查看。
天澄技术杂谈
2019/04/05
1.2K0
玩懂Python垃圾回收机制,又有时间可以摸鱼了
我们写过C语言、C++的朋友们都知道,C语言是没有垃圾回收这种说法的。手动分配以及释放内存都是需要我们的程序员自己动手完成。不管是“内存泄漏” 还是野指针都是让开发者非常头疼的问题。所以C语言开发提及讨论最多的话题就是内存管理了。but对于其他高级语言来说,例如Java、C#、Python等高级语言,已经具备了垃圾回收机制。这样可以屏蔽内存管理的复杂性,使开发者可以更好的关注核心的业务逻辑。
查理不是猹
2021/12/12
9120
垃圾回收机制
完整高频题库仓库地址:https://github.com/hzfe/awesome-interview
HZFEStudio
2021/09/19
5140
2018年8月26日python中的垃圾回收机制(Garbage Collection:GC)
垃圾回收机制(Garbage Collection:GC)基本是所有高级语言的标准配置之一了
武军超
2018/09/27
1.1K0
2018年8月26日python中的垃圾回收机制(Garbage Collection:GC)
python高阶教程-对象管理与垃圾回收
我们可使用copy模块中的函数来复制一个复杂对象,主要分为shallow copy和deep copy两类
羽翰尘
2019/11/20
6700
说说Python中的垃圾回收机制?
小猿会从最基础的面试题开始,每天一题。如果参考答案不够好,或者有错误的话,麻烦大家可以在留言区给出自己的意见和讨论,大家是要一起学习的 。
程序员小猿
2021/01/19
4320
python垃圾回收机制原理
#python垃圾回收机制详解 一、概述:   python的GC模块主要运用了“引用计数(reference counting)”来跟踪和回收垃圾。在引用计数的基础上,还可以通过标记清除(mark and sweep)解决容器(这里的容器值指的不是docker,而是数组,字典,元组这样的对象)对象可能产生的循环引用的问题。通过“分代回收(generation collection)”以空间换取时间来进一步提高垃圾回收的效率。 二、垃圾回收三种机制   1、引用计数   在Python中,大多数对象的生命周期都是通过对象的引用计数来管理的, 广义上讲,它也是一种垃圾回收机制,而且是一种最直观最简单的垃圾回收机制。   原理:当一个对象被创建引用或者被复制的时候,对象的引用计数会加一,当一个对象的引用被销毁时,对象的引用计数会减一,当对象的引用计数减为0的时候,就意味着对象已经没有被任何人使用了,可以将其所占用的内存释放了。   虽然引用计数必须在每次分配和释放内存的时候加入管理引用计数的这个动作,然而与其他主流垃圾收集机制相比, 最大的一个优点是实时性, 及任何内存,一旦没有指向他的引用,就会立即被回收,其他的垃圾回收机制必须在某种特殊条件下(内存分配失败)才能进行无效内存的回收。   执行效率问题: 引用计数机制带来的维护引用计数带来的额外操作与python运行中所运行的内存分配和释放,引用赋值的次数是成正比的。相比其他机制,比如“标记-清除”,“停止-复制”,是一个弱点,因为这些技术所带来的操作基本上只是与待回收的数量有关。 引用计数还存在的一个致命的弱点是循环引用,这使得垃圾回收机制从来没有将引用计数包含在内。这就需要我们用新的方法了, 即标记清除。 2、标记清除 标记清除主要是用来解决循环引用产生的问题的,循环引用只会在容器对象中才会产生,比如数组、字典、元组等,首先是为了追踪对象,需要每个容器对象维护两个额外的指针,用来将容器对象组成一个链表,指针分别指向前后两个容器对象,这样就可以将对象的循环引用环摘除,就可以得出两个对象的有效计数。 问题说明:   循环引用可以使得一组对象的引用计数不是0, 然而这些对象实际上并没有被外部对象所引用,这就意味着不会再有人使用这组对象, 应该回收这组对象所占用的内存空间,然而由于相互引用的存在,每一个对象的引用计数不为0,因为这些对象所占用的内存永远不会被释放。比如下面的代码:
全栈程序员站长
2022/09/12
4140
python垃圾回收机制原理
python垃圾回收机制
原理 对象之间通过引用构建有向图,从root object(全局变量,寄存器等不可删除的对象)出发,沿着有向边遍历对象,可达的对象标记为活跃对象,不可达的对象就是要被清除的非活动对象。
编程黑洞
2023/03/06
3150
python垃圾回收机制
Python 垃圾回收机制与原理解析
Python 作为一门解释型语言,以代码简洁易懂著称,我们可以直接对名称赋值,而不必声明类型,名称类型的确定、内存空间的分配与释放都是由 Python 解释器在运行时进行的
公众号机器学习与AI生成创作
2021/10/20
1.1K0
Python 垃圾回收机制与原理解析
垃圾回收机制
  我们定义变量会申请内存空间来存放变量的值,而内存的容量是有限的,当一个变量值没有用了(称为垃圾),就应该将其占用的内存给回收掉。变量名是访问到变量的唯一方式,所以当一个变量值没有任何关联的变量名时,我们就无法访问到该变量了,该变量就是一个垃圾,会被python解释的垃圾回收机制自动回收。
py3study
2020/01/17
7150
简述Python垃圾回收机制「建议收藏」
由此可知python还将引入新的回收机制(标记-清除,分代回收),辅助引用计数机制完成内存的管理
全栈程序员站长
2022/07/02
4400
简述Python垃圾回收机制「建议收藏」
C#-垃圾回收机制(GC)
The garbage collector is a common language runtime component that controls the allocation and release of managed memory。
郑子铭
2023/08/29
2.4K0
C#-垃圾回收机制(GC)
js垃圾回收机制
程序媛夏天
2024/01/18
2260
垃圾回收之 Python PHP Java Go 对比
本文对比了四种语言在垃圾回收方面的实现,其目标都是相同的,即希望做到准确又高效的识别和清理内存中的垃圾对象,不同语言之间在实现思路上有相似之处,又各自有不同的侧重点。
菜皮日记
2023/12/18
4340
垃圾回收之 Python PHP Java Go 对比
Python垃圾回收机制详解「建议收藏」
  平时在写代码的时候,关注的是写出能实现业务逻辑的代码,因为现在计算机的内存也比较宽裕,所以写程序的时候也就没怎么考虑垃圾回收这一方面的知识。俗话说,出来混总是要还的,所以既然每次都伸手向内存索取它的资源,那么还是需要知道什么时候以及如何把它还回去比较好。嘻嘻。
全栈程序员站长
2022/11/19
2.1K0
Python垃圾回收机制详解「建议收藏」
matinal:PYTHON 的垃圾回收机制
Python GC主要使用引用计数(reference counting)来跟踪和回收垃圾。在引用计数的基础上,通过“标记-清除”(mark and sweep)解决容器对象可能产生的循环引用问题,通过“分代回收”(generation collection)以空间换时间的方法提高垃圾回收效率。 (1).引用计数 PyObject是每个对象必有的内容,其中ob_refcnt就是作为引用计数。当一个对象有新的引用时,它的ob_refcnt就会增加,当引用它的对象被删除,它的ob_refcnt就会减少。引用计数为0时,该对象的生命就结合了。 优点:简单,实时性 缺点:维护引用计数消耗资源,循环引用 (2).标记-清除机制 基本思路是先按需分配,等到没有空闲内存的时候从寄存器和程序栈上的引用出发,遍历以对象为节点,以引用为边构成的图,把所有可以访问到的对象打上标记,然后清扫一边内存空间,把所有没有标记的对象释放。 (3).分代技术 分代回收的整体思想是:将系统中的所有内存根据其存活时间划分不同的集合,每个集合就成为一个“代”,垃圾收集频率随着代的存活时间的增大而减小,存活时间通常利用几次垃圾回收来度量。 python默认定义了三代对象集合,索引数越大,对象存活时间越长。 举例: 当某些内存块M经过了3次垃圾收集的清洗之后还存活时,我们就将内存块M划到一个集合A中去,而新分配的内存都划分到集合B中去。当垃圾收集开始工作时,大多数情况都只对集合B进行垃圾回收,而对集合A进行垃圾回收要隔相当长一段时间后才进行,这就使得垃圾收集机制需要处理的内存少了,效率自然就提高了。在这个过程中,集合B中的某些内存块由于存活时间长而会被转移到集合A中,当然,集合A中实际上也存在一些垃圾,这些垃圾的回收会因为这种分代的机制而被延迟。
matinal
2023/10/14
1820
python中的垃圾回收机制
Python GC主要使用引用计数(reference counting)来跟踪和回收垃圾。在引用计数的基础上,通过“标记-清除”(mark and sweep)解决容器对象可能产生的循环引用问题,通过“分代回收”(generation collection)以空间换时间的方法提高垃圾回收效率。
Tim在路上
2020/08/04
4390
相关推荐
一文读懂Python垃圾回收机制【收藏版】
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档