python垃圾回收 采用方式_python 写入文本Python内存管理方式和垃圾回收算法解析...

在列表,元组,实例,类,字典和函数中存在循环引用问题。有 __del__ 方法的实例会以健全的方式被处理。给新类型添加GC支持是很容易的。支持GC的Python与常规的Python是二进制兼容的。

分代式回收能运行工作(目前是三个分代)。由 pybench 实测的结果是大约有百分之四的开销。实际上所有的扩展模块都应该依然如故地正常工作(我不得不修改了标准发行版中的 new 和 cPickle 模块)。一个叫做 gc 的新模块马上就可以用来调试回收器和设置调试选项。

回收器应该是跨平台可移植的。Python 的补丁版本通过了所有的回归测试并且跑 Grail、Idle 和 Sketch 的时候没有任何问题。

自 Python 2.0 和之后的版本,可移植的垃圾回收机制已经包括在其中了。垃圾回收默认是开启的。请高兴些吧!

为什么我们需要垃圾回收?

目前版本的 Python 采用引用计数的方式来管理分配的内存。Python 的每个对象都有一个引用计数,这个引用计数表明了有多少对象在指向它。当这个引用计数为 0 时,该对象就释放了。引用计数对于多数程序都工作地很好。然而,引用计数有一个本质上的缺陷,是由于循环引用引起的。循环引用最简单的例子就是一个引用自身的对象。比如:>>> l = []

>>> l.append(l)

>>> del l

这个创建的列表的引用计数现在是 1。然而,因为它从 Python 内部已经无法访问,并且可能没法再被用到了,它应该被当作垃圾。在目前版本的 Python 中,这个列表永远不会被释放。

电脑技术网对《python 写入文本Python内存管理方式和垃圾回收算法解析》总结来说,为我们学习电脑很实用。

一般情况下循环引用不是一个好的编程实践,并且几乎总该被避免。然而,有时候很难避免制造循环引用,要么则是程序员甚至没有察觉到循环引用的问题。对于长期运行的程序,比如服务器,这个问题特别令人烦恼。人们可不想他们的服务器因为循环引用无法释放访问不到的对象而耗尽内存。对于大型程序,很难发现循环引用是怎么创造出来的。

“传统的”垃圾回收是怎样的?

传统的垃圾回收(比如标记-清除法或者停止-拷贝法)通常工作如下:

找到系统的根对象。根对象就像是全局的环境(比如 Python 中的 __main__ 模块)和堆栈上的对象。

从这些对象搜索所有的可以访问的对象。这些对象都是“活跃”的。

释放其他所有对象。

不幸的是这个方法不能用于当前版本的 Python。由于扩展模块的工作方式,Python 不能完全地确定根对象集合。如果根对象集合没法被准确地确定,我们就有释放仍然被引用的对象的风险。即使用其他方式设计扩展模块,也没有可移植的方式来找到当前 C 堆栈上的对象。而且,引用计数提供了一些 Python 程序员已然期待的有关局部性内存引用和终结语义的好处。最好是我们能够找到一个即能使用引用计数,又能够释放循环引用的的办法。

这个方法如何工作?

从概念上讲,这个方法与传统垃圾回收机制相反。这个方法试图去找到所有的不可访问对象,而不是去找所有的可访问对象。这样更加安全,因为如果这个算法失败了,起码不会比不进行垃圾回收还要糟(不考虑我们浪费掉的时间和空间)。

因为我们仍然在用引用计数,垃圾回收器只需要找到循环引用。引用计数会处理其他类型垃圾。首先我们观察到循环引用只能被容器对象创造。容器对象是可以包含其他对象的引用的对象。在Python中,列表、字典、实例、类和元祖都是容器对象的例子。整数和字符串不是容器。通过这个发现,我们意识到非容器对象可以被垃圾回收忽略。这是一个有用的优化因为整数和字符串这样的应该比较轻快。

现在我们的想法是记录所有的容器对象。有几种方法可以做到,然而最好的一种办法是利用双向链表,链表中的对象结构中包含指针字段。这样就可以使对象从集合中快速插入删除,而且不需要额外内存空间分配。当一个容器被创建,它就插入这个集合,被删除时,就从集合中去除。

既然我们能够得到所有的容器对象,我们怎么找到循环引用呢?首先我们往容器对象中添加两个指针外的另一个字段。我们命名这个字段 gc_refs。通过以下几步我们可以找到循环引用:

对每个容器对象,设 gc_refs 的值为对象的引用计数。

更多:python 写入文本Python内存管理方式和垃圾回收算法解析

https://www.002pc.comhttps://www.002pc.com/python/4751.html

你可能感兴趣的Python,内存,算法,解析,垃圾,回收

No alive nodes found in your cluster

0踩

0 赞

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值