Python垃圾回收机制--完美讲解!

虽然是自己转载的但是是真的好的一篇图文并茂的对垃圾回收机制的讲解!!!

先来个概述,第二部分的画述才是厉害的。

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

引用计数机制:
python里每一个东西都是对象,它们的核心就是一个结构体:PyObject
在这里插入图片描述
PyObject是每个对象必有的内容,其中ob_refcnt就是做为引用计数。当一个对象有新的引用时,它的ob_refcnt就会增加,当引用它的对象被删除,它的ob_refcnt就会减少
在这里插入图片描述

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

引用计数机制的优点:

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

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

画说 Ruby 与 Python 垃圾回收

英文原文: visualizing garbage collection in ruby and python
中文:画说 Ruby 与 Python 垃圾回收

本文基于我在刚刚过去的在布达佩斯举行的RuPy上的演讲。我觉得趁热打铁写成帖子应该会比只留在幻灯片上更有意义。你也可以看看演讲录像。再跟你说件事,我在Ruby大会也会做一个相似的演讲,但是我不会去说Python的事儿,相反我会对比一下MRI,JRuby和Rubinius的垃圾回收机制。
想了解Ruby垃圾回收机制和Ruby内部实现更详尽的阐述,请关注即将问世的拙作
《Ruby Under a Microscope》。
在这里插入图片描述
既然是"Ruby Python"大会,我觉得对比一下Ruby和Python的垃圾回收机制应该会很有趣。在此之前,到底为什么要计较垃圾回收呢?毕竟,这不是什么光鲜亮丽激动人心的主题,对吧。你们大家有多少人对垃圾回收感冒?(竟然有不少RuPyde与会者举手了!)

最近Ruby社区发表了一篇博文,是关于如何通过更改Ruby GC设置来为单元测试提速的。我认为这篇文章是极好的。对于想让单元测试跑得更快和让程序GC暂停更少的人来说很有裨益,但是GC并没能引起我的兴趣。第一瞥GC就像是一个让人昏昏欲睡的、干巴巴的技术主题。

但是实际上垃圾回收是一个迷人的主题:GC算法不仅是计算机科学史的重要组成部分,也是一个前沿课题。举例来说,MRI Ruby使用的标记-清除算法已经年逾五旬了,而Ruby的替代语言Rubinius使用的GC算法在不久前的2008年才被发明出来。

然而, "垃圾回收"这个词其实有些用词不当。

应用程序那颗跃动的心
GC系统所承担的工作远比"垃圾回收"多得多。实际上,它们负责三个重要任务。它们

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

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

一个简单的例子
运用实例一贯有助于理论的理解。下面是一个简单类,分别用Python和Ruby写成,我们今天就以此为例:
在这里插入图片描述
顺便提一句,两种语言的代码竟能如此相像:Ruby 和 Python 在表达同一事物上真的只是略有不同。但是在这两种语言的内部实现上是否也如此相似呢?

可用列表
当我们执行上面的Node.new(1)时,Ruby到底做了什么?Ruby是如何为我们创建新的对象的呢?
出乎意料的是它做的非常少。实际上,早在代码开始执行前,Ruby就提前创建了成百上千个对象,并把它们串在链表上,名曰:可用列表。下图所示为可用列表的概念图:

在这里插入图片描述
想象一下每个白色方格上都标着一个"未使用预创建对象"。当我们调用 Node.new ,Ruby只需取一个预创建对象给我们使用即可:
在这里插入图片描述
上图中左侧灰格表示我们代码中使用的当前对象,同时其他白格是未使用对象。(请注意:无疑我的示意图是对实际的简化。实际上,Ruby会用另一个对象来装载字符串"ABC",另一个对象装载Node类定义,还有一个对象装载了代码中分析出的抽象语法树,等等)

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值