新闻中心

EEPW首页 > 嵌入式系统 > 设计应用 > 对比Ruby和Python的垃圾回收

对比Ruby和Python的垃圾回收

作者:时间:2016-09-12来源:网络收藏

当然内部也会由于各种原因使用空闲对象链表(它使用链表循环确定对象),为对象和值分配内存的方式常常不同于

本文引用地址:http://www.eepw.com.cn/article/201609/304199.htm

假设我们创建一个Node对象使用

pythobvdfbfdbdfbn1

Python不同于,当你创建对象的时候,Python会立即向操作系统申请分配内存。(Python 事实上实现了自己的内存分配系统,它在操作系统内存堆上提供了另外一层抽象,但是今天没有事件深入探讨。 )

当我们创建第二个对象时,Python将再次向操作系统申请更多的内存:

python2fbfdhhrt

看起来相当简单,当我们创建Python对象的时刻,将花费事件申请内存。

menbfgnfgnfhss

将没有用的对象扔的到处都是,直到下一个过程

Ruby开发者生活在一个脏乱的房间

回到Ruby,由于我们分配越来越多的对象,Ruby将继续为我们从空闲对象链表(free list)获取预分配对象。因此,空闲对象链表将变得越来越短:

fregergregrgge-list4

或者更短:

freederfreferfg-list5

请注意,我将一个新的值赋给了n1,Ruby会遗留下旧的值。”ABC”, “JKL”和”MNO”等结点对象会依然保留在内存中。Ruby不会立即清理旧的对象尽管程序不再使用!作为一名Ruby开发者就像生活在一个脏乱的房间,衣服随意的仍在地板上,厨房的水槽中堆满了脏盘子。作为一个Ruby开发者,你必须在一大堆垃圾对象中去工作。

clfgdgergerggrean

当你的程序不在使用任何对象的时候,Python会立刻进行清理。

Python开发者生活在一所整洁的房子

机制在Python和Ruby中迥然不同,让我们回到前面三个Python中Node对象的例子:

pythfgbfgbfgbnfgon3b

内部的,每当我们新建一个对象,Python将在对象对应的C语言结构中保存一个数字,叫做引用技术。最初,Python将它的值设为1。

pytefwefwefwefghon4

值为1表明每个对象有一个指针或引用指向它。假设我们创建一个新的对象,JKL:

pythgbfgbfbfgbon5

正如前面所说,Python将”JKL”的引用计数设置为1。同样注意到我们改变n1指向了”JKL”,不再引用”ABC”,同时将”ABC”的引用计数减少为0。

通过这一点,Python器将会立即执行!无论何时,只要一个对象的引用计数变为0,python将立即释放这个对象,并且将它的内存返回给操作系统。

pythgfbfgbfgnbfgnon6

上图中,Python将回收”ABC”对象的内存。记住,Ruby只是将旧的对象遗留在那里并且不去释放它们占用的内存。

这种垃圾回收算法被称为”引用计数”,由乔治柯林斯发明于1960年。非常巧合的是在同一年约翰麦卡锡大叔发明了”空闲对象链表算法”。正如Mike Bernstein在Ruby Conference大会上所说”1960年是属于垃圾回收器的…”。

作为一个Python开发者,就像生活在一个整洁的房间中。你知道,你的室友有些洁癖,他会把你使用过的任何东西都清洗一遍。你把脏盘子,脏杯子一放到水槽中他就会清洗。

现在看另外一个例子,假设我们让n2和n1指向同样的结点:

pytvwefwefwefhon8

上图左边可以看到,Python减少了”DEF”的引用计数并且立即回收了”DEF”对象。同时可以看到,由于n1和n2同时指了”JKL”对象,所以它的引用计数变为了2。

标记回收算法

最终脏乱的房间将堆慢垃圾,生活不能总是如此。Ruby程序在运行一段时间之后,空闲对象链表最终将被用尽。

mark-fthrthand-sweep1

上图中所有的预分配对象都被用尽(方块全部变成了灰色),链表上没有对象可用(没有剩余的白色方块)。

此时,Ruby使用了一种由约翰麦卡锡发明的被称为”标记回收”的算法。首先,Ruby将停止程序的执行,Ruby使用了”停止这个世界,然后回收垃圾”的方式。然后,Ruby会扫描所有的指向对象和值的指针或引用。同样,Ruby也会迭代虚拟机内部使用的指针。它会标记每一个指针所能到达的对象。在下图中,我使用了”M”指出了这些标记:



关键词: Ruby Python 垃圾回收

评论


相关推荐

技术专区

关闭