目录
在python中,每个对象都有指向该对象的引用总数---引用计数
gc.get_threshold(threshold0[,threshold1,threshold2])
Python的垃圾回收机制
Python采用引用计数为主,隔代回收机制为辅的策略
在python中,每个对象都有指向该对象的引用总数---引用计数
举例说明:
class TestObject(object):
def __init__(self):
print("当前对象已经创建,占用内存地址为:%s"%hex(id(self)))
a = TestObject()
print("当前对象的引用计数为:%s"%sys.getrefcount(a))
测试引用计数,这里引用计数个数为2,因为在创建a对象的时候被引用的一次,接着将a作为形参又被引用了一次,所以这里总共两次
引用计数的个数可以增加和减少,分别如下
引用计数的增加方法:
- 对象被创建(每创建一个对象,引用计数就会多一个)a = TestObject()
- 另外变量也指向当前对象
- 作为容器对象的一个元素
Python中的容器有列表,字典,元组,集合等
就是将创建的对象作为容器中的一个元素(将该对象添加到容器中)
- 作为参数提供给函数(引用计数的举例中使用的就是这个方法,将a作为形参)例如:sys.getrefcount(a)
引用计数的减少方法“
- 变量被显式的销毁
说明:这里因为使用了del显式将a对象销毁掉了所以这里将b作为对象进行测试输出
- 对象的另外一个变量重新赋值
说明: b由原来引用a到现在重新赋值,导致引用计数减一
- 从容其中移除
说明:之前向列表中添加对象a,现在移除对象a就可以使引用计数减一
- 函数被执行完毕,该函数里面的局部变量的引用计数就会减一(全局变量不会)
关于引用计数的总结
当python的某个对象的引用计数降为0时,说明没有任何引用指向该对象,该对象就成为要被回收的垃圾,比如某个新建对象,被分配给某个应用,对象的引用计数为1,如果引用被删除,对象的引用计数会降为0.这时该对象就可以被垃圾回收(简单粗暴理解就是:当一个东西没有任何利用价值的时候,就会被当作垃圾进行回收处理)释放该对象占用的内存空间
隔代回收机制
说明:
三个链表,零链表上的对象(新创建的对象都加入到零链表),引用计数都是一,每增加一个指针引用就会加一,当零号链表上部分对象无法使用隔代回收机制进行回收,就会自动转到一号链表上,如果一号链表上回收不了,就会转到二号链表上依次类推。
隔代回收机制是为了解决交叉引用(循环引用),并增加数据回收的效率
说明:这里就出现了交叉引用,将b赋值给a的pro属性,将a赋值给b的pro属性,出现这种交叉情况,该情况下就不能单独的使用引用计数的机制进行垃圾回收,这时候就需要使用隔代回收机制(后面的两句执行,不是主动的垃圾回收机制执行的,是因为我们这里的程序执行结束了,所以会自动清空所有的对象进行垃圾回收)
隔代回收机制的触发:
隔代回收触发的时机(GC阈(yu)值)-----(700,10,10)
Gc模块的使用(常用函数)
gc.get_count()
#获取当前自动执行垃圾回收的计算器,返回一个长度为3的列表,如(这234,2,1)
gc.get_threshold()
#获取gc模块中自动执行垃圾回收机制的频率
gc.get_threshold(threshold0[,threshold1,threshold2])
#设置自动执行垃圾回收的频率
gc.get_disable()
#python中默认开启gc机制,可以使用该方法进行关闭gc机制的操作
gc.collect()
#手动调用垃圾回收机制回收垃圾
测试隔代回收机制的触发
class TestObject(object):
def __init__(self):
print("当前对象已经创建,占用内存地址为:%s"%hex(id(self)))
def __del__(self):
print("当前对象马上会触发触发GC回收")
while True: #使用while true得到多个对象
a = TestObject()
b = TestObject()
a.pro = b
b.pro = a
del a
del b
print(gc.get_threshold()) #打印隔代回收的阈值
print(gc.get_count()) #打印GC需要回收的对象的数量
time.sleep(0.3)
未达到700这个阈值之前如下图所示:
达到700这个阈值之后的结果如图,会将超过阈值部分传递给一链表,以此类推,如下图所示:
注意:
gc.get_count()`返回的元组中的值是在特定的环境和垃圾回收器算法下可能有规律的,但并不总是固定的。
垃圾回收器的工作原理是基于对象的引用计数和分代回收机制。引用计数表示了一个对象被其他对象引用的次数。当对象的引用计数为0时,说明没有任何引用指向该对象,可以将其回收。而分代回收机制则是将对象按照其存活时间的长短分为不同的代,并根据代的不同选择不同的回收策略。垃圾回收的触发时机和算法都是由Python解释器根据具体情况自动管理的。
因此,`gc.get_count()`返回的值会在垃圾回收过程中根据对象的创建、引用和回收情况而动态变化。具体的规律取决于对象的引用关系、分代回收的配置以及垃圾回收器的内部算法。不同的环境和算法下,这些值也可能会有不同的规律。因此,无法一概而论地说`gc.get_count()`返回的元组有固定的规律。
隔代回收机制和引用计数应用于以下场景:
内存管理:
引用计数机制是Python中最基本的垃圾回收机制。它通过跟踪对象的引用计数来确定是否可以回收一个对象。当一个对象的引用计数为0时,垃圾回收器会自动回收该对象的内存,释放资源。
循环引用:
隔代回收机制主要用于解决循环引用(circular references)的问题。循环引用是指两个或多个对象之间相互引用形成的环,导致它们的引用计数无法达到0,从而无法被回收。隔代回收机制通过将对象按照存活时间划分为不同的代,对不同代的对象采用不同的回收策略,从而解决循环引用带来的内存泄漏问题。
大内存对象管理:
隔代回收机制还可以提供对大内存对象的有效管理。在Python中,将大型对象分配给新的代可以延迟其垃圾回收,从而提高程序的执行效率。这对于处理大型数据集、图像处理等场景中的对象管理非常有用。
总结
引用计数和隔代回收机制是Python中两种常用的垃圾回收机制。引用计数适用于轻量级的对象管理,能够及时回收对象并释放内存。而隔代回收机制则适用于解决循环引用和大内存对象管理等场景下的内存泄漏问题。这两种机制的结合使用,能够有效地帮助开发者管理和优化内存资源的使用。