Python中GC的使用

作者: python 发布时间: 2022-10-16 浏览: 498 次 编辑

Python中GC的使用

一、python的垃圾回收机制

引用计数为主,分代回收为辅

引用计数:python中一切皆为对象,核心是一个结构体PyObject其中维护了一个int型变量ob_refcnt。

当对象有新的引用时候ob_refcnt就会增加1,同理删除就会减少。其中还有小整数对象池,大整数对象池等概念。此处就不在记录

但此时会有一个十分严重的问题就是循环引用无法回收

什么是循环引用呢,就是 如果⼀个数据结构引⽤了它⾃身, 即如果这个数据结构是⼀个循环数据结构, 那么某些引⽤计数值是肯定⽆法变成零的。比如循环链表,此处举一个简单的例子

class ClassA():
	def __init__(self):
		print('Object born,id:%s'%str(hex(id(self))))
def f2():
	while True:
		c1=ClassA()
		c2=ClassA()
		c1.t=c2
		c2.t=c1
		del c1
		del c2
 
 
 
f2()

在执行del c1和c2时候,由于c1有指向c2的引用,c2有指向c1的引用。del之后两者引用数只会减少到1,并不会被回收。

二、隔代回收

在python程序内部每创建一个对象,就会将对象分到一代中,每个代就是一个链表,代进行标记-清除的时间 与 代内对象存活时间成正比例关系。

当Python运行时,会记录其中分配对象(object allocation)和取消分配对象(object deallocation)的次数,当两者的差值高于某个阈值时就触发GC回收机制。具体怎么排查,将0代放到1代,我也不知道。还有就只分配对象和取消分配对象怎么理解?有人知道么???

另外还有两种情况下会触发GC机制:2、调用gc.collect() 3、程序退出

三、获取对象的引用计数

import sys
 
a=[1,2,3]
getrefcount(a)
Out[4]: 2
#之所以是2是因为a作为参数传给了getrefcount

四、对gc使用的介绍

<1>、gc.collect([generation]) 显式进⾏垃圾回收, 可以输⼊参数, 0代表只检查第⼀代的对象, 1代表检查⼀, ⼆代的对象, 2代表检查⼀, ⼆, 三代的对象, 如果不传参数, 执⾏⼀个full collection, 也就是等于传2。

<2>、 gc.get_threshold() 获取的gc模块中⾃动执⾏垃圾回收的频率返回阀值!

<3>、 gc.set_threshold(threshold0[, threshold1[, threshold2]) 设置阀值。

<4>、 gc.get_count() :Return the current collection counts as a tuple of (count0, count1, count2).