Python的垃圾回收机制GC(持续更新~)

我们知道,计算机的内存是有限的,我们让计算机帮我们干活,也就是处理数据,这些数据会占用计算机的内存,那么如果不合理的使用有限的内存,很快就会内存占满,导致计算机干不动活了。

在我们让计算机帮我们跑程序的时候,会进行大量的数据存储和计算,占用的内存空间,如果不及时的清理,那么就会出现内存泄露(我看有的文章或者视频说是内存溢出,但是我觉得不是,内存泄露就是申请的内存空间没有被释放,导致一直占着这个坑,不干活,所以叫内存泄露,而内存溢出,就是比如我需要给一个数据申请一块内存空间,但是这个内存空间不够放的,那么这个就是内存溢出。)
回到正题,内存本来就是有限的,你再给我泄露一点,那么可用的就变得更少了。

所以,为了解决合理利用内存空间,每个语言都有自己的内存回收机制,也就是垃圾回收机制,GC(garbage collection),Python也一样。

Python的垃圾回收机制是由它变量(其实叫对象,因为Python中一切皆对象)定义的方式来决定的,我们知道Python的变量声明的时候,是不指定类型的,声明的时候必须赋值,否则会报错,并且Python的变量声明之后,是给变量一个值的引用,并不是和c语言一样,直接就给这个变量分配块空间存放它的值了。
声明一个变量:a = 1,其实就是在内存中开辟一个空间放置值1,然后把值1的引用,也就是相当于地址的东西给a,那么a就能够访问1.此时1的被引用的次数就变成了1.
在这里插入图片描述
如果这个时候,再声明一个变量:b=a.那么就相当于b也拿到了1的引用,它们同时指向1,这个时候1的引用次数为:2
在这里插入图片描述
那么,如果我们声明了很多变量,内存占用也会增多,可用的变少,内存中的数据肯定分为:已经不使用的和正在使用的,那么计算机如何知道哪些被使用,哪些没有被使用呢,那就是引用,如果一块内存中的数据,没有被引用,也就是引用的次数为0,那么就认为这个数据是垃圾数据,大于0次数的引用认为是有用的数据,垃圾数据肯定是及时清理掉,才能释放掉内存空间,给别的程序使用。
所以Python的垃圾回收机制就是当一块内存中的数据被申请后,他会有一个变量叫refchain变量,用来存放这个数据被引用的次数,被引用一次,就会加1.删除引用,就会减1,当减为0的时候,这个数据就会被Python的垃圾回收器给回收了,这块内存就会被释放,给别人使用。

上面的垃圾回收机制看着没什么问题,挺简单的。但是有一种特殊情况的数据,会被漏掉,什么样的数据呢,就是普通的数据,只是这个数据被别的数据引用,别的数据还引用它。其实这两块数据并没有在外部被使用,导致它们自己形成了一个环,这个环就叫做循环引用。
比如下面的代码就会导致形成环:

a = [1]
b = [2]
a.append(b)
b.append(a)

print(a,b)

在内存中引用是下面这样的:
在这里插入图片描述
可以看到上面变量a和变量b分别指向两块内存空间,这两块内存空间,内部互相引用。如果这个时候,del a 和del b.只会是下面这样:
在这里插入图片描述
也就是a和b对这两块的内存的引用都切断了,但是这两块内存的引用次数仍然不为0,就是因为它们内部互相引用,这样的话,Python的垃圾回收机制就会认为这是个有用的数据,会保留,导致这块内存在程序运行期间一直存在,这样肯定是不行的,如果存在很多这样的数据,那么就会导致内存被浪费很多。为了解决这个循环引用的问题。就引出了标记-清除的一种垃圾回收方案。

循环引用一般出现在可以包含其他对象引用的数据类型上,比如**(list dict class set)**

在介绍标记-清除之前,再给一个例子看下,当一个数据在内存中的引用为0时,会自动调用__del__方法;

class INT(int):
    def __del__(self):
        print("我被释放了")
        
a = INT(1)
print(a,type(a))
a = 3
print(a,type(a))

运行结果:

1 <class '__main__.INT'>
我被释放了
3 <class 'int'>

可以看到在把3的引用给a的时候,1的引用已经没了,这个时候会自动去调用del方法,而我们重写了这个方法,所以能够看到打印。

接下来介绍标记-清除:

上面的介绍说:标记-清除是为了解决垃圾回收中循环引用的问题,就是说

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

如梦@_@

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值