Python专家解读垃圾回收<<一>>

简介: Python专家解读垃圾回收<<一>>

没有坚定不移的信心,任何行动都会失败。——华·欧文


1. 前言



Garbage collection(GC)


现在的高级语言如java,c#等,都采用了垃圾收集机制,而不再是c,c++里用户自己管理维护内存的方式。自己管理内存极其自由,可以任意申请内存,但如同一把双刃剑,为大量内存泄露,悬空指针等bug埋下隐患。对于一个字符串、列表、类甚至数值都是对象,且定位简单易用的语言,自然不会让用户去处理如何分配回收内存的问题。python里也同java一样采用了垃圾收集机制,不过不一样的是: python采用的是引用计数机制为主,标记-清除和分代收集两种机制为辅的策略。


2. 引用计数机制



python里每一个东西都是对象,它们的核心就是一个结构体:PyObject


typedef struct_object {
        int ob_refcnt;
        struct_typeobject *ob_type;
    } PyObject;


PyObject是每个对象必有的内容,其中ob_refcnt就是做为引用计数。当一个对象有新的引用时,它的ob_refcnt就会增加,当引用它的对象被删除,它的ob_refcnt就会减少


#define Py_INCREF(op)   ((op)->ob_refcnt++) //增加计数
   #define Py_DECREF(op) \ //减少计数
        if (--(op)->ob_refcnt != 0) \
            ; \
        else \
             __Py_Dealloc((PyObject *)(op))


当引用计数为0时,该对象生命就结束了。


引用计数机制的优点

  1. 简单
  2. 实时性:一旦没有引用,内存就直接释放了。不用像其他机制等到特定时机。实时性还带来一个好处:处理回收内存的时间分摊到了平时。


引用计数机制的缺点

  1. 维护引用计数消耗资源
  2. 循环引用


list1 = []
  list2 = []
  list1.append(list2)
  list2.append(list1)


list1与list2相互引用,如果不存在其他对象对它们的引用,list1与list2的引用计数也仍然为1,所占用的内存永远无法被回收,这将是致命的。对于如今的强大硬件,缺点1尚可接受,但是循环引用导致内存泄露,注定python还将引入新的回收机制。(标记清除和分代收集)


3. 画说 Python 垃圾回收



应用程序那颗跃动的心

GC系统所承担的工作远比"垃圾回收"多得多。实际上,它们负责三个重要任务。它们

  1. 为新生成的对象分配内存
  2. 识别那些垃圾对象,并且
  3. 从垃圾对象那回收内存


如果将应用程序比作人的身体:所有你所写的那些优雅的代码,业务逻辑,算法,应该就是大脑。以此类推,垃圾回收机制应该是那个身体器官呢?(我从RuPy听众那听到了不少有趣的答案:腰子白血球 :) )


我认为垃圾回收就是应用程序那颗跃动的心。像心脏为身体其他器官提供血液和营养物那样,垃圾回收器为你的应该程序提供内存和对象。如果心脏停跳,过不了几秒钟人就完了。如果垃圾回收器停止工作或运行迟缓,像动脉阻塞,你的应用程序效率也会下降,直至最终死掉。

一个简单的例子: 运用实例一贯有助于理论的理解。下面是一个简单类,我们今天就以此为例:

640.png


Python 的对象分配


我们已经了解了Ruby预先创建对象并将它们存放在可用列表中。那Python又怎么样呢?

尽管由于许多原因Python也使用可用列表(用来回收一些特定对象比如 list),但在为新对象和变量分配内存的方面Python和Ruby是不同的。

例如我们用Pyhon来创建一个Node对象:


640.png

当创建对象时Python立即向操作系统请求内存。(Python实际上实现了一套自己的内存分配系统,在操作系统堆之上提供了一个抽象层。但是我今天不展开说了。)

当我们创建第二个对象的时候,再次像OS请求内存:

看起来够简单吧,在我们创建对象的时候,Python会花些时间为我们找到并分配内存。


Ruby 开发者住在凌乱的房间里

640.png

Python 开发者住在卫生之家庭


640.png


Python与Ruby的垃圾回收机制颇为不同。让我们回到前面提到的三个Python Node对象:


640.png

在内部,创建一个对象时,Python总是在对象的C结构体里保存一个整数,称为 引用数。期初,Python将这个值设置为1:

640.png


值为1说明分别有个一个指针指向或是引用这三个对象。假如我们现在创建一个新的Node实例,JKL:

640.png

与之前一样,Python设置JKL的引用数为1。然而,请注意由于我们改变了n1指向了JKL,不再指向ABC,Python就把ABC的引用数置为0了。


此刻,Python垃圾回收器立刻挺身而出!每当对象的引用数减为0,Python立即将其释放,把内存还给操作系统:

640.png


上面Python回收了ABC Node实例使用的内存。记住,Ruby弃旧对象原地于不顾,也不释放它们的内存。Python的这种垃圾回收算法被称为引用计数。是George-Collins在1960年发明的,恰巧与John McCarthy发明的可用列表算法在同一年出现。就像Mike-Bernstein在6月份哥谭市Ruby大会杰出的垃圾回收机制演讲中说的: "1960年是垃圾收集器的黄金年代..."


Python开发者工作在卫生之家,你可以想象,有个患有轻度OCD(一种强迫症)的室友一刻不停地跟在你身后打扫,你一放下脏碟子或杯子,有个家伙已经准备好把它放进洗碗机了!

现在来看第二例子。加入我们让n2引用n1:


640.png

上图中左边的DEF的引用数已经被Python减少了,垃圾回收器会立即回收DEF实例。同时JKL的引用数已经变为了2 ,因为n1和n2都指向它。


4. 小结



由于篇幅的关系,我们今天就写到这里,下篇我们继续Python垃圾回收机制  (二),欢迎点赞转发和关注。


5. 关注公众号



 微信公众号:堆栈future

相关文章
|
1月前
|
数据采集 设计模式 算法
拥抱变化:从Python新手到专家的旅程
【10月更文挑战第5天】在编程的世界里,Python以其简洁明了的语法和强大的功能库成为了无数开发者的首选语言。本文将带你走进一个Python新手如何一步步成长为专家的故事,探索学习过程中的困惑、挑战以及最终的成就,并通过代码示例揭示学习之旅的关键时刻。
30 2
|
2月前
|
机器学习/深度学习 测试技术 数据处理
KAN专家混合模型在高性能时间序列预测中的应用:RMoK模型架构探析与Python代码实验
Kolmogorov-Arnold网络(KAN)作为一种多层感知器(MLP)的替代方案,为深度学习领域带来新可能。尽管初期测试显示KAN在时间序列预测中的表现不佳,近期提出的可逆KAN混合模型(RMoK)显著提升了其性能。RMoK结合了Wav-KAN、JacobiKAN和TaylorKAN等多种专家层,通过门控网络动态选择最适合的专家层,从而灵活应对各种时间序列模式。实验结果显示,RMoK在多个数据集上表现出色,尤其是在长期预测任务中。未来研究将进一步探索RMoK在不同领域的应用潜力及其与其他先进技术的结合。
97 4
|
2月前
|
缓存 Java Python
python垃圾回收&缓存机制
python垃圾回收&缓存机制
|
2月前
|
存储 算法 Java
关于python3的一些理解(装饰器、垃圾回收、进程线程协程、全局解释器锁等)
该文章深入探讨了Python3中的多个重要概念,包括装饰器的工作原理、垃圾回收机制、进程与线程的区别及全局解释器锁(GIL)的影响等,并提供了详细的解释与示例代码。
29 0
|
2月前
|
机器学习/深度学习 数据挖掘 TensorFlow
从数据小白到AI专家:Python数据分析与TensorFlow/PyTorch深度学习的蜕变之路
【9月更文挑战第10天】从数据新手成长为AI专家,需先掌握Python基础语法,并学会使用NumPy和Pandas进行数据分析。接着,通过Matplotlib和Seaborn实现数据可视化,最后利用TensorFlow或PyTorch探索深度学习。这一过程涉及从数据清洗、可视化到构建神经网络的多个步骤,每一步都需不断实践与学习。借助Python的强大功能及各类库的支持,你能逐步解锁数据的深层价值。
67 0
|
3月前
|
算法 Java 开发者
Python垃圾回收机制
Python垃圾回收机制
|
3月前
|
监控 Java 数据处理
Python内存管理:引用计数与垃圾回收
Python内存管理:引用计数与垃圾回收
45 0
|
5月前
|
Java Python
Python进阶之旅:深入理解变量作用域、垃圾回收、拷贝机制与异常处理
Python进阶之旅:深入理解变量作用域、垃圾回收、拷贝机制与异常处理
|
5月前
|
监控 算法 Java
使用Python的垃圾回收机制来管理内存
使用Python的垃圾回收机制来管理内存
|
4月前
|
算法 安全 Java
Python的垃圾回收机制是什么?
【7月更文挑战第2天】Python的垃圾回收机制是什么?
26 0
下一篇
无影云桌面