您的位置:首页 > 编程语言 > Python开发

Python中的垃圾回收和引用环的处理

2018-02-23 14:59 267 查看
和Java语言一样,Python也有自己的垃圾回收机制。当Python中的对象越来越多的时候,会占用大量的内存空间,在某个时机,Python会自己“瘦身”,对垃圾进行回收。
从基本原理来说,Python中记录了每个对象的引用次数,当引用次数为0的时候,就要被当做垃圾进行回收。在Python中通常用del语句来显示的删除对象的引用。虽然有这种机制存在,但是运行是需要耗费一些资源的,如果内存4G,数据有100M,都是垃圾数据,Python也可能不进行垃圾回收的,因为进行垃圾回收的时候,Python不能进行别的任务。
Python会自动的进行垃圾回收机制,主要是Python会记录每个对象的分配次数和取消分配的次数,如果两个差值大于某个阈值的话,Python会自动的进行垃圾回收。阈值的查看,我们可以借助gc模块,首先导入import gc 接着调用 gc.get_threshold()方法,接着会返回一个有三个元素的阈值,比如(700,10,10)。这里的700就是我们需要查看的阈值,后面两个10下面再说。如果我们想要手动的启动垃圾回收,可以显示的调用gc.collect()手动的完成垃圾回收。
其实在Python中,还有分代回收。有兴趣的可以自己查资料阅读。后面的两个10,也是和分代回收相关的参数。分代回收是因为在Python中,将对象划分为0,1,2代对象,所有的新建对象都是0代对象,然后0代对象经历过10次扫描之后,对1代对象进行扫描,扫描10次之后,对2代对象进行扫描1次,然后对所有的0,1,2对象进行扫描。这里出现的两个10 ,就是上面返回的两个参数,如果想要修改,可以这样使用:gc.set_threshold(700,10,5) 表示的是0代对象扫描10次,1代对象扫描1次,1代的对象扫描对象扫描5次之后,扫描2代对象。也许会有疑问,0,1,2代对象如何划分,所有新建的对象是0代对象,当经历过某代的扫描存活下来之后,提升为下一代。比如0代的某些对象,经历过10次扫描之后,依然存活,我们就把这个对象提升为1代的对象……
这里再介绍一下引用环的产生,Python是一种动态类型的语言,引用和对象是分离的,在我们创建两个对象,并引用对方,这样每个对象都有一个指向,a指向b,b也指向a,它们不会被垃圾回收掉,但是又没有存在的意义,那么Python中的垃圾回收机制是怎么解决这种相互引用的对象呢?
Python会复制每个对象的引用计数,比如有两个相互引用的对象a和b,此时a的引用计数我们用gc_ref_a 来表示,同理用gc_ref_b 来表示b的引用计数,然后Python会遍历所有的引用对象,这里只有a和b,遍历到a的时候,a指向b,将 b的gc_ref_b的值减1,同理遍历b的时候将a的gc_ref_a的值减1,结果他们的值都为0,最后将不为0的对象保留,为0 的对象进行垃圾回收。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息