Python正课6 —— 垃圾回收机制
本文内容皆为作者原创,如需转载,请注明出处:https://www.cnblogs.com/xuexianqi/p/12421927.html
一:什么是 “垃圾” ?
x = 1 #把 “1” 这个值赋给 “x”,在计算机中,先是定义了一个变量x,然后在内存里面开辟了一块内存空间,用来存放x的值,也就是1,这个时候,x和1是绑定的。
就像游戏里的人物穿上了装备之后,装备就和人物绑定了。这种绑定关系,叫做 “引用计数”。,这时候,“1”的引用计数就是1.
如果在这个时候,再一次给x赋值,x = 2,那么这个时候,计算机就重新开辟了一块内存空间,用来存放x的值,也就是2,存放了2之后,x和之前的1就自动解绑了。
就像游戏里人物换上了新的装备,旧装备就被弃置了。这个时候,1的引用计数就变成0了,因为没有被引用,无法被访问到,(就像占着茅坑不拉屎)变成一个孤儿了,计算机就把它视为“垃圾”。
二:什么是垃圾回收机制?
垃圾回收机制(garbage collection,简称 “gc”)
Python的垃圾回收机制主要采用的是引用计数为主、标记清除与隔代回收为辅的垃圾回收策略。
简单来说,是专门用来回收不可用变量值所占用的内存空间的一种机制。
三:为什么要用垃圾回收机制?
大多数程序在运行过程中会申请的内存空间,对于一些无用的内存空间如果不及时清理就会出现一种叫做 “内存溢出” 的情况,导致程序奔溃。
因此内存管理是一件非常重要且繁琐的事情,而垃圾回收机制能够把程序猿从繁琐的内存管理中解放出来。
四:垃圾回收机制的原理
1.循环引用
l1=[111,] #此时l1被引用一次,引用计数为1
l2=[222,] #此时l2被引用一次,引用计数为1
l1.append(l2) # l1=[值111的内存地址,l2列表的内存地址]#此时l2又被引用一次,引用计数为2
l2.append(l1) # l2=[值222的内存地址,l1列表的内存地址]#此时l1又被引用一次,引用计数为2
# print(id(l1[1])) #l1引用l2
# print(id(l2))
# print(id(l2[1])) #l2引用l1
# print(id(l1))
# print(l2)
# print(l1[1])
#此时,l1和l2互相引用
del l1 #l1引用次数-1
del l2 #l2引用次数-1
#但是此时我们却无法访问l1列表内的内容,本该被当做垃圾删除,但是他的引用计数为1,被l2列表间接引用。这个时候引用计数在这种垃圾身上就失效了。
2.标记清除 —— 堆区 与 栈区
在定义变量时,变量名与变量值都是需要存储的,分别对应内存中的两块区域:堆区与栈区。
① 变量名与值内存地址的关联关系存放于栈区
②变量值存放于堆区,内存管理回收的则是堆区的内容
先定义2个变量:x = 100,y = 200
当执行了x = y 时,会发现如下变化:
Python的GC模块主要运用了“引用计数”(reference counting)来跟踪和回收垃圾。
在引用计数的基础上,还可以通过“标记-清除”(mark and sweep)解决容器对象可能产生的循环引用的问题
并且通过“分代回收”(generation collection)以空间换取时间的方式来进一步提高垃圾回收的效率。
3.分代回收
分代,顾名思义,就是分成不同的等级
以班级为例,可以把学生分为三类:学霸、普通学生、学渣
学霸:过于优秀,一周查一次作业
普通学生:一般般,三天查一次
学渣:不用多说,每天都查
虽然分级检查了,检查的时间效率变高了,但是存在着缺陷,如果学霸不交作业,要下一周才能
查出来,那他的学霸地位就不保了,存在漏洞。