返回介绍

对象的垃圾收集

发布于 2024-01-29 22:24:17 字数 1334 浏览 0 评论 0 收藏 0

在上一节的例子中,我们把变量a赋值给了不同类型的对象。但是当重新给变量a赋值时,它前一个引用值发生了什么变化?例如,在下边的语句中,对象3发生了什么变化?

答案是,在Python中,每当一个变量名被赋予了一个新的对象,之前的那个对象占用的空间就会被回收(如果它没有被其他的变量名或对象所引用的话)。这种自动回收对象空间的技术叫做垃圾收集。

为了讲清楚,考虑下面的例子,其中每个语句,把变量名x赋值给了不同的对象:

首先注意x每次被设置为不同类型的对象。再者,尽管这并不是真正的情况,效果却是x的类型每次都在改变。在Python中,类型属于对象,而不是变量名。由于变量名只是引用对象而已,这种代码自然行得通。

第二,注意对象的引用值在此过程中逐个丢弃。每一次x被赋值给一个新的对象,Python都回收了对象的空间。例如,当它赋值为字符串'shrubbery'时,对象42马上被回收(假设它没有被其他对象引用):对象的空间自动放入自由内存空间池,等待后来的对象使用。

在内部,Python是这样来实现这一功能的:它在每个对象中保持了一个计数器,计数器记录了当前指向该对象的引用的数目。一旦(并精确在同一时间)这个计数器被设置为零,这个对象的内存空间就会自动回收。在前面的介绍中,假设每次x都被赋值给一个新的对象,而前一个对象的引用计数器变为零,就会导致它的空间被回收。

垃圾收集最直接的、可感受到的好处就是,这意味着可以在脚本中任意使用对象而不需要考虑释放内存空间。在程序运行时,Python将会清理那些不再使用的空间。实际上,与C和C++这样的底层语言相比,省去了大量的基础代码。

注意:从技术上讲,Python的垃圾收集主要基于引用计数器,正如前面所介绍的。然而,它也有一部分功能可以及时地检测并回收带有循环引用的对象。如果你确保自己的代码没有产生循环引用,可以关闭这部分功能,但该功能是默认可用的。

由于引用实现为指针,一个对象有可能会引用自身,或者引用另一个引用了自身的对象。例如,第一部分末尾的练习3及其在附录B中的解答,展示了如何把一个列表的引用嵌入其自身中,从而创建一个循环。对来自用户定义的类的对象的属性赋值的时候,会产生同样的现象。尽管相对很少,由于这样的对象的引用计数器不会清除为0,必须特别对待它们。

要了解Python的循环检测器的更多细节,参见Python库手册中gc模块的文档。还要注意,这里对于Python的垃圾收集器的介绍只适用于标准的Cpython、Jython和IronPython且可能使用不同的方案,尽管直接效果都是类似的,都是未使用的空间又自动重新申请。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文