Python垃圾回收
共 2458字,需浏览 5分钟
·
2022-01-09 06:39
在计算机科学中,GC 是一种自动的内存管理机制。当对应内存不再需要的时候,就应该予以释放,这种内存资源管理,称为垃圾回收。而且垃圾回收器会自行进行垃圾对象的处理,可以让程序员减少很多负担,也减少了程序员犯错误的机会。
垃圾回收
我们作为Python
程序员也是非常幸福的,我们日常不太需要关注内存管理和垃圾回收,是因为CPython
的解释器有一套自己的机制来处理。那么,在Python
的世界里为什么不太需要关注垃圾回收呢?
这是因为Python
自己的解释器自动做了垃圾回收相应的处理,在绝大部分场景下是不需要人为的干涉的。另外,大家对于Python
的共识就是开发效率。因为其是一个胶水语言,在很多场景下高性能以及内存问题其实并不凸显,而且现在服务器资源很便宜而人力资源很贵的情况下。
使用Python
做Web
开发,工作很多年也不太会遇到内存管理和垃圾回收的。在Web
应用几乎都是使用多进程模型的,一则是会有定期超时重启的机制,二是每次上线的操作也会进程的重启。所以不会有某个进程长时间的驻留,使其占用很多内存,导致内存泄漏。所以,GC
的缺陷基本不太会对Web
开发产生很大的影响。且CPython
也足够完善,基本不太会出现内存泄漏这样的问题。大部分场景下,都是因为开发者错误的使用或者是误判导致内存占用不正常。
引用计数
Python
的垃圾回收是建立在引用技术上的,所以理解引用计数也是非常重要的。而引用计数的原理就是,当一个对象的引用被创建或者复制时,对象的引用计数加1
;当一个对象的引用被销毁时,对象的引用计数减1
;当对象的引用计数减少为0
时,就意味着对象已经没有被任何人使用了,可以将其所占用的内存立刻释放了。
引用计数这种机制的特点是,有比较好的实时性,但是引用计数会有一个循环引用的问题。比如说A
引用了B
,而B
又引用了A
,导致每一个对象的引用计数都不为0
,那么A
和B
占用的内存资源永远都不会被回收。所以,就需要一些回收算法来解决这个问题,而Python
就是使用了标记清除和分代回收机制。
sys.getrefcount()
标记清除
A
和B
,其中A
有一个B
的引用,就会将B
的引用计数减1
。然后顺着引用达到B
,因为B
有一个引用了A
,同样将A
的引用计数减少1
。这样,就将引用计数中循环引用的环给摘除。A
,它有一个对象C
的引用,而C
并没有引用A
。如果将C
的引用计数减少1
,而最后A
没有被回收,显然我们错误将C
的引用计数减少了1
。这样,将导致在未来的某个时段出现了一个对C
的悬空引用。这就要求我们在C
没有被删除的情况下,复用C
的引用计数。如果采用这样方案的话,那么维护这个引用计数的复杂度就会成倍的增加。而这个标记清除采用了更好的做法来解决这个问题。分代回收
Python
将所有的对象分为0
、1
、2
三代,所有的新建对象都是0
代对象。但是,当某一代对象经历过垃圾回收,依然存活,那么它就被归入下一代对象,即1
代或者2
代了。(700, 10, 10)
。其中第一个数值700
表示,从上一个垃圾回收到现在分配内存的数目减去释放内存的数目。如果这个数值到了700
,则会对第一代的垃圾对象进行回收,并且给第二个数值加1
。当第二个数值增加到10
的时候,就会对第一代和第二代的垃圾对象进行回收,并且给第三个数值加1
。当第三个数值增加到10
的时候,则三代都会被回收,然后初始化为(0, 0, 0)
并继续开始计数。In [1]: import gc
In [2]: gc.get_threshold()
Out[2]: (700, 10, 10)
强制回收
Python
的自动垃圾回收机制,而Python
也支持在某一刻特定的时间点,使用gc.collect()
方法强制回收。不会,通常我们是不适用强制回收的,而是使用下面这种禁用垃圾回收的方式。禁用垃圾回收
GC
的一个场景就是,某一段代码中需要加载大量的原始数据,尤其是有大量的新建、删除对象这样的操作。也就是执行某一段代码的时候,会自动触发很多次的垃圾回收。但是,我们需要知道Python
执行垃圾回收的时候,它会暂停当前的工作。所以,这种工作耗时越多就会拖累我们程序的运行时间。gc.set_threshold(0)
而不用gc.disable
这种写法。是因为有些第三方的库会隐式的启用GC
让gc.disable
不起作用了,而使用gc.set_threshold(0)
就不会有第三方的库把垃圾回收开启了,除非我们想要把它开启。gc.disable()
do somethings
gc.enable()
原文链接:https://www.escapelife.site/posts/57aa800d.html
文章转载:Python编程学习圈
(版权归原作者所有,侵删)
点击下方“阅读原文”查看更多