美工做兼职在那个网站,wordpress内容主题,怎么制作一个个人网站,网站界面颜色搭配Python中的垃圾回收机制是自动的#xff0c;它主要使用了引用计数来追踪和回收内存。
1、引用计数
当一个对象被创建时#xff0c;就会被分配一块内存#xff0c;然后将其引用计数设置为1。当另一个变量引用该对象时#xff0c;引用计数就会增加1。当一个对象的引用计数变…Python中的垃圾回收机制是自动的它主要使用了引用计数来追踪和回收内存。
1、引用计数
当一个对象被创建时就会被分配一块内存然后将其引用计数设置为1。当另一个变量引用该对象时引用计数就会增加1。当一个对象的引用计数变为0时说明该对象没有任何引用Python解释器就会将其回收并释放相应的内存。
下面给个例子去解释引用计数
1、误区例子
import sysa 1
print(f对象a{sys.getrefcount(a)-1})
b 10
print(f对象a{sys.getrefcount(a)-1}对象b{sys.getrefcount(b)-1})
# 输出结果
# 对象a96
# 对象a96对象b14如图我这a,b在例子中只引用了一次但输出结果可知a和b的引用计数不是一次是因为python自带的由整数常量池 [-5, 256] 在这个区间的整数被称为小整数对象所以自定义一个其他类型的数据。
那我用一个整数常量池之外的数据尝试一下
在 .py文件中内存地址是一样的 在终端执行内存地址是不一样的 由两图可知解释器将 .py文件进行编译的时候逐行进行解释发现a和b的变量的内存地址一样解释器会优化代码则将两个变量指向同一块内存地址以减少内存的开销。
2、正确例子
import sysclass X:passa X() # a引用次数加1print(f对象a{sys.getrefcount(a)-1})
c a # a引用次数加1, c引用次数为a的引用次数2
print(f对象a{sys.getrefcount(a)-1}, 对象c{sys.getrefcount(c)-1})# 输出结果
# 对象a1
# 对象a2, 对象c2引用次数加1条件
对象被创建例如a1
对象被引用例如ba
对象被作为参数传入到一个函数中例如func(a)
对象作为一个元素存储在容器中例如 a_list[a,a]引用次数减1条件
对象被显式销毁如del a。
变量重新赋予新的对象例如a1。
对象离开它的作用域如函数执行完毕时函数中的局部变量全局变量不会。
对象所在的容器被销毁或从容器中删除对象。这样的缺点是假如循环引用的话其引用计数一直不为0就不会被回收就会浪费资源就引进了下面两种方式进行回收。
2、标记清除
标记标记所有能够被程序访问到的对象root objects如全局变量、栈中的变量等将它们标记为“活跃”对象对于标记的对象遍历它们的引用将引用的对象标记为“活跃”对象 清除对于未被标记的所有对象将它们标记为“垃圾”即将它们回收清除。 class X:def aaa(self):return 1
def func():a3 X().aaa()a2 3 a3 # 为了表明a2是跟a3相关的a1 a2 a3 # 为了表明a1是跟a2a3相关的c1 a2c2 c1 a1b1 X()b2 X()b1.obj b2b2.obj b1return [a1, a2, a3]A func()如图Aa1a2a3b1b2c1c2都是被标记的对象其中Aa1a2a3都被标记为“活跃”对象b1b2c1c被标记为“垃圾”垃圾就进行回收“活跃”对象就进行保存。 因为只有“活跃”对象到最后一步被使用“垃圾”没有被使用
3、分代回收
1、将所有收集的对象放到一起 2、遍历集合中的所有对象将其分为两个引用计数为0和引用计数大于0的两个集合 3、大于0的放到更老的一代等于0的进行回收 4、或者是触发了GC中的阈值进行回收
设置各世代的阈值
import gc
threshold gc.get_threshold()
print(各世代的阈值:, threshold)# 设置各世代阈值
# gc.set_threshold(threshold0[, threshold1[, threshold2]])
gc.set_threshold(800, 20, 20)threshold gc.get_threshold()
print(各世代的阈值2:, threshold)在执行分代回收的时候程序会被暂停就譬如说你嗑瓜子是将瓜子扔在地上的你妈妈正在扫地假如你一直嗑瓜子你妈妈就一直会扫不干净。为了减少程序暂停时间就采用分代回收去收集清理垃圾来减少耗时。
4、什么是阈值
Python分代回收中的阈值是指两个用于判断对象是否应该被垃圾回收的阈值第一个是每代的阈值第二个是总体的阈值。
每代的阈值指的是每个分代的垃圾回收阶段执行的次数。每当达到每代的阈值时Python会触发分代垃圾回收。
总体的阈值则是用于在分代回收期间控制是否触发全局垃圾回收即回收所有代的阈值。当某个分代的垃圾回收次数达到总体的阈值时Python会触发全局垃圾回收。
这两个阈值都可以通过gc.get_threshold()函数获取它返回一个三元组 (gen0, gen1, gen2)其中 gen0 为每代的阈值 gen1 为总体的阈值。