Python为什么不太需要关注垃圾回收呢?

85 阅读7分钟

引用计数这种机制的特点是,有比较好的实时性,但是引用计数会有一个循环引用的问题。比如说A引用了B,而B又引用了A,导致每一个对象的引用计数都不为0,那么A和B占用的内存资源永远都不会被回收。所以,就需要一些回收算法来解决这个问题,而Python就是使用了标记清除和分代回收机制。

标记清除

上面我们说了,标记-清除就是为解决循环引用的问题。最理想的情况下,比如说有两个对象A和B,其中A有一个B的引用,就会将B的引用计数减1。然后顺着引用达到B,因为B有一个引用了A,同样将A的引用计数减少1。这样,就将引用计数中循环引用的环给摘除。

但是,还会存在另外一个问题。假设对象A,它有一个对象C的引用,而C并没有引用A。如果将C的引用计数减少1,而最后A没有被回收,显然我们错误将C的引用计数减少了1。这样,将导致在未来的某个时段出现了一个对C的悬空引用。这就要求我们在C没有被删除的情况下,复用C的引用计数。如果采用这样方案的话,那么维护这个引用计数的复杂度就会成倍的增加。而这个标记清除采用了更好的做法来解决这个问题。

标记清除采用了更好的做法,它并不改动真实的引用计数,而是将集合中对象的引用计数复制一份副本,改动该对象引用的副本。对于副本做任何的改动,都不会影响到对象生命周期的维护。

分代回收

分代回收是在面试中,常常会被问到的一个问题。分代回收的核心思想就是,对象存活的时间越长,越不可能是垃圾,应该更少的去回收。且Python将所有的对象分为0、1、2三代,所有的新建对象都是0代对象。但是,当某一代对象经历过垃圾回收,依然存活,那么它就被归入下一代对象,即1代或者2代了。

分代回收的预值,可以使用如下代码进行查看。通常,返回一个元组且包含三个数值,默认值为(700, 10, 10)。其中第一个数值700表示,从上一个垃圾回收到现在分配内存的数目减去释放内存的数目。如果这个数值到了700,则会对第一代的垃圾对象进行回收,并且给第二个数值加1。当第二个数值增加到10的时候,就会对第一代和第二代的垃圾对象进行回收,并且给第三个数值加1。当第三个数值增加到10的时候,则三代都会被回收,然后初始化为(0, 0, 0)并继续开始计数。

需要注意的是,如果没有十分必要的场景,这个分代回收的默认值通常是不需要我们人为的改动的。

In [1]: import gc

In [2]: gc.get_threshold()

Out[2]: (700, 10, 10)

强制回收

上面介绍了Python的自动垃圾回收机制,而Python也支持在某一刻特定的时间点,使用gc.collect()方法强制回收。不会,通常我们是不适用强制回收的,而是使用下面这种禁用垃圾回收的方式。

禁用垃圾回收

这个垃圾回收机制不是挺好的,那我们会什么还要禁用呢。通常我们禁用GC的一个场景就是,某一段代码中需要加载大量的原始数据,尤其是有大量的新建、删除对象这样的操作。也就是执行某一段代码的时候,会自动触发很多次的垃圾回收。但是,我们需要知道Python执行垃圾回收的时候,它会暂停当前的工作。所以,这种工作耗时越多就会拖累我们程序的运行时间。

那我们怎么办呢?我们通常都会在执行这段代码之前,禁用垃圾回收,执行完之后再手动开启。熟悉开源项目的同学可以会看到,有些项目中会使用gc.set_threshold(0)而不用gc.disable这种写法。是因为有些第三方的库会隐式的启用GC让gc.disable不起作用了,而使用gc.set_threshold(0)就不会有第三方的库把垃圾回收开启了,除非我们想要把它开启。

gc.disable()

do somethings
gc.enable()
好啦,今天的分享就到这里结束啦。 大家有什么补充的或者需要我改进的都可以在讨论区进行讨论哦。不要忘记一键三连呀!

最后

Python崛起并且风靡,因为优点多、应用领域广、被大牛们认可。学习 Python 门槛很低,但它的晋级路线很多,通过它你能进入机器学习、数据挖掘、大数据,CS等更加高级的领域。Python可以做网络应用,可以做科学计算,数据分析,可以做网络爬虫,可以做机器学习、自然语言处理、可以写游戏、可以做桌面应用…Python可以做的很多,你需要学好基础,再选择明确的方向。这里给大家分享一份全套的 Python 学习资料,给那些想学习 Python 的小伙伴们一点帮助!

👉Python所有方向的学习路线👈

Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。

👉Python必备开发工具👈

工欲善其事必先利其器。学习Python常用的开发软件都在这里了,给大家节省了很多时间。

👉Python全套学习视频👈

我们在看视频学习的时候,不能光动眼动脑不动手,比较科学的学习方法是在理解之后运用它们,这时候练手项目就很适合了。

👉实战案例👈

学python就与学数学一样,是不能只看书不做题的,直接看步骤和答案会让人误以为自己全都掌握了,但是碰到生题的时候还是会一筹莫展。

因此在学习python的过程中一定要记得多动手写代码,教程只需要看一两遍即可。

👉大厂面试真题👈

我们学习Python必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。

了解详情:docs.qq.com/doc/DSnl3ZG…