两个对象相互引用,即构成了所谓的 引用环 :
a = []
b = [a]
a.append(b)
objgraph.show_refs([a,b], filename=‘a-b.png’)
即使是单个对象,只需自己引用自己,也会构成引用环:
a = []
a.append(a)
objgraph.show_refs([a], filename=‘a-b.png’)
del 关键字除了可以删除容器中的元素,还可以删除某个引用。
4、垃圾回收
CPython中的内存管理和垃圾回收有两个策略:
-
引用计数
-
分代回收
4.1 引用计数
CPython中主要的垃圾收集机制是通过引用计数,且引用计数无法被禁用,而后面谈到的分代回收策略则可以禁止。
原理上,Python的某个对象的引用计数变为0时,就要成为被回收的垃圾了。例如:
a = [1,2,3]
del a
当垃圾回收启动时,Python扫描到这个引用计数为0的对象,会将其所占据的内存清空。而垃圾回收是个费时费力的事,垃圾回收期间Python不能进行其他任务。频繁的垃圾回收会大大降低Python的效率,所以Python只会在特定条件下启动垃圾回收。Python运行时,会记录其中分配对象和取消分配对象的次数,当两者差值高于某个 阈值 ,垃圾回收才会启动。
4.2 分代回收
除了上面这种 实时的 , 自动的 基于引用计数的垃圾回收实现方法,Python还同时采用 分代回收 策略,这一次略的基本假设是,存活时间越久的对象,越不可能在以后成为垃圾。Python将所有对象分为三代,所有新建对象都是0代,如果经过一次扫描没被回收即成为了1代,以此类推。
Python的基于引用计数的方法是自动的,并且是实时发生的,而分代垃圾回收模块的操作是周期性的,可以手动调用,常用API:
-
get_shreshold()
方法可以查看触发垃圾收集的阈值: -
gc.get_count()
方法可以查看内存中当前存在的各代对象数量 -
gc.set_threshold()
方法可以更改触发垃圾收集的阈值
‘’’
遇到问题没人解答?小编创建了一个Python学习交流QQ群:531509025
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
‘’’
import gc
print(gc.get_threshold()) # (700, 10, 10)
gc.set_threshold(700.10,5) # 2代垃圾回收会更频繁
gc.collect() # 手动触发垃圾回收
对于每一代,垃圾收集器模块都有一个阈值对象。如果对象数超过该阈值,则垃圾收集器将触发收集过程,在该过程中幸存下来的对象会被归为下一代。默认情况下,Python对于最年轻的一代的阈值为700,对于两个较老的一代中的每个阈值为10。
引用环的回收
现在能在网上找到很多很多的学习资源,有免费的也有收费的,当我拿到1套比较全的学习资源之前,我并没着急去看第1节,我而是去审视这套资源是否值得学习,有时候也会去问一些学长的意见,如果可以之后,我会对这套学习资源做1个学习计划,我的学习计划主要包括规划图和学习进度表。
分享给大家这份我薅到的免费视频资料,质量还不错,大家可以跟着学习
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!