Python的垃圾回收机制

本文深入探讨了Python中的垃圾回收机制,包括对象引用计数的工作原理及其如何影响内存管理。文章解释了Python如何通过跟踪引用计数来确定何时回收不再使用的对象,并介绍了分代回收的概念,说明了Python如何根据不同对象的生存周期调整回收频率。

作者:Wilson_Iceman 出处:http://blog.youkuaiyun.com/Wilson_Iceman 欢迎转载, 但请保留这段声明。多谢!

今天我们来谈谈Python中的垃圾回收机制,每一种语言都有自己的垃圾回收机制,从C语言的手动回收,到java,js和python的自动回收,每一种回收机制都有自己的特点,今天我们来谈谈python的垃圾回收机制,看看它是怎么工作的。

关于引用

第一个问题是有关引用的,其实在我之前的文章可变与不可变类型中已经谈到了这个问题,我们再回忆一下。先看最简单的例子,赋值

>>>a = 1

整数1是一个对象(Python中一切皆对象),而a是一个引用,通过赋值语句,将a指向了对象1。在Python中,对象与引用的分开的,这样做的好处是可以节省内存。在Python中,每个对象都存在一个存有指向该对象的引用总数,即引用计数。我们可以通过系统自带的getrefcount来查看该对象的引用计数。

from sys import getrefcount
import gc

a = [1, 2, 3]
print(getrefcount(a))
b = a
print(getrefcount(b))
print(getrefcount(a))
a = 1
print(getrefcount(b))

上面的运行结果是

>>>2
>>>3
>>>3
>>>2
注意在运行getrefcount的时候,对自动创建一个对象的临时引用,因此会再加1。a引用了一次,加1就是2。b有引用了a,因此b应用了2次,再加1是3,。而此时a和b引用同一个对象,因此a也是3。a再被赋值1,此时b就少了一次引用,因此b变成1,再加1就是2。

通过上面的例子,我们可以看到对象的引用计数可能增加,也可能减少。我们简单总结一下:

引用计数增加的情况:

  • 对象被创建。a = 1
  • 对象被引用。b = a
  • 对象被作为参数传入给函数。do_sth(a)
  • 作为容器对象的元素。mylist = [a, b, c]
引用计数减少的情况:
  • 作用域丢失。比如上面的函数do_sth(a)结束,则a引用计数减1
  • 对象被显式销毁。del a
  • 对象的别名被赋值给其他对象。a = 1,之后a = 2,则之前的对象1的引用会减1
  • 从一个容器对象中剔除。mylist.remove(a)
  • 容器对象本身被销毁。del mylist
关于回收机制

了解了上面的内容,我们就可以很容易的理解Python的回收机制,即当该对象的引用计数为0时,该对象就会被回收。这个其实很好理解,对于一个引用计数为0的对象,说明它的引用已经没有了,因此也没有存在的必要了。Python就不时的扫描文件中所有对象的引用计数,当一个对象的引用计数为0时,Python就会把它回收,同时释放掉它所在的内存。

但是这样存在一个问题,就是当程序中存在大量的对象时,那么检查对象的引用计数将会变成一件非常耗时耗资源的事情, 但是我们的python非常聪明,它有自己的办法来解决这个问题,即 分代回收

关于分代回收

简单的说就是存活越久的对象,就越不可能成为垃圾,自然就越不会被回收,那既然是这样,那么存活越久的对象,应该越不会

被扫描到。Python其实就是这么干的,它把对象分成0代对象,1代对象和2代对象。对象在被建立时都是0代对象,当经历过Python

几次扫描后依然存在,那么它就会“竞升”为1代对象,以此类推“竞升”为2代对象。Python对不同代对象,扫描的频率是不一样的,

们可以通过get_threshold()来检查一下。

import gc

print(gc.get_threshold())
上面的程序运行后会返回(700,10,10),有三个值,第一个值700是一个阈值,它表示Python启动垃圾回收的条件,即,产生对象

和销毁对象的次数超过这个阈值时,Python才会启动垃圾回收机制。后面两个值10分别表示,启动扫描10次0代对象,才会扫描1次1代

对象,扫描10次1代对象,才会扫描1次2代对象。当然我们也可以通过set_threshold()函数来修改这3个参数。

以上就是今天的全部内容。

与您共勉!






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值