Python中的垃圾收集(GC)
在C、C++中,用户自己管理维护内存的方式,操作内存非常的繁琐,后来的一些新式语言如Java、Python等,都采用了垃圾收集机制(Garbage Collection)。对于⼀个字符串、列表、类甚至数值都是对象,且定位简单易用的语⾔,自然不会让用户去处理如何分配回收内存的问题。Python中采用的是引用计数机制为主,标记-清除和分代收集两种机制为辅的策略。
引用计数
获取引用计数时,可以使用sys.getrefcount来获取。
例如:
import sys
a = [1, 2, 3, 4]
print(sys.getrefcount(a)) # 2
这里只引用了一次a,之所以多出来一次,是因为这是ipython环境额外的多一次对变量的监控,这里不用管它,正常情况下的结果为1.
将a赋值给b,这时的引用计数会是???
import sys
a = [1, 2, 3, 4]
b = a
print(sys.getrefcount(a)) # 3
如果删除b,这时的引用计数会是???
import sys
a = [1, 2, 3, 4]
b = a
del b
print(sys.getrefcount(a)) # 2
这时,我们会发现a多一次引用就会加1,少一次引用就会减1,这就是所谓的引用计数。python在解释器内部会为每一个变量都存放一个计数器。
同时,我们可以在https://pytutor.seamile.cn/visualize.html#mode=edit网页中可以看到其引用变化。
x1 = [1, 2, 3]
x2 = [9, 8, 7]
x1.append(x2)
x2.append(x1)
del x2
del x1
部分展示:
引用计数的优点:简单、实时性高
引用计数的缺点:消耗资源、循环引用无法解决
标记-清除和分代收集
标记-清除:python3中在进行运算的时候,每隔5毫秒,整个程序停顿一次,把整个的内存空间扫描一次,发现哪些东西已经没有外部引用的时候,给其添加标志,当5毫秒结束的时候,进行清除。
分代收集:其是对整体的内存做一个预判,会把内存主要分为三代,第一次扫描有垃圾时,直接清除,第三次扫描后还存在,则不算为垃圾。
其作用:用来回收引用计数无法清除的内存。