python的垃圾回收机制

1.一个对象,会记录着自身被引用的个数。
2.每增加一个引用,这个对象的引用计数会自动+1。
3.每减少一个引用,这个对象的引用计数会自动-1。

查看引用计数

import sys 
sys.getrefcount(对象)

举个例子

import sys

class Test:
    pass

a = Test()
print sys.getrefcount(a)-1  # 显示1(其中包含自己本身算一次引用,所以需要减一)
b = c = a
print sys.getrefcount(a)-1  # 显示3
print sys.getrefcount(b)-1  # 显示3
del b
print sys.getrefcount(a)-1  # 显示2


def func(obj):
    print(sys.getrefcount(obj)-1)
func(a)  # 显示4

什么时候会被引用

  1. 对象被创建会 +1
    a=Test()
  2. 对象被引用会 +1
    c=a
  3. 对象作为参数传入到一个函数中会 +2
  4. 对象作为一个元素,存储在容器中会 +1
    list1=[a]

引用减的场景

  1. 对象被销毁
    del a
  2. 对象被赋予新的值
    a=Test()
    a=1
  3. 一个对象离开他的作用域
    如上面对象(func)传入某个函数中,当函数执行完成后,引用会立即销毁
  4. 对象所在的容器被销毁
    list1=[a] del list1

python垃圾回收机制

从经历过引用计数器机制仍未被释放掉的对象中,找到循环引用并删除相关对象

何时启动垃圾回收

  • 不是说你创建了一个变量,就会马上开始垃圾回收的!
    需要你代码中,新增对象-消亡对象阈值达到某一个零界点是才会启动垃圾回收
    如何查看这个阈值呢?需要引入GC模块
import gc
print(gc.get_threshold())

output:
(700, 10, 10)

代码的结果是一个元组,700代表python设置的阈值

循环引用的回收

  1. 搜集所有容器对象,通过双向列表进行引用
  2. 针对每一个容器对象,通过一个变量gc_refs来记录当前对应的引用计数
  3. 对于每一个容器对象,找到它引用的容器对象,并将这个容器对象的引用计数-1
  4. 如果经历以上三次,如果一个容器对象的引用次数为0,就代表可以被回收了

分代回收

如果一个大的项目,存在着成千上万的容器对象,python会进行分代回收,当第一次检测完成后,部分的容器对象没有为0,则将其从0代移动至1代对象中,当检测10次后,在第11次时,会再次扫描0代1代的对象,当101次,即1代对象也被检测了10次,仍存在未被回收的容器对象时,会将器移动至2代中。多像爷爸孙…
至于为什么是10,就是刚才我们查看gc.get_threshold()得到的元组后两个字段

gc模块一些命令

垃圾回收的开启、关闭、状态查询

  • 垃圾回收机制,默认都是开启的,当然我们可以进行调整
    gc.disable()
    gc.enable()
    gc.isenabled()

如何手动触发垃圾回收

  • 通过gc.collect()手动触发垃圾回收。
    此处需要注意一点,即便目前的垃圾回收机制处于关闭状态,一样可以手动触发。

如何避免循环引用

  1. 使用弱引用模块
import weakref
A.master = weakref.ref(P) # 此时会生成弱引用
  • 何为弱引用,即在引用的时候,不会是计数器+1
    但是weakref.ref只是针对单个引用的,如果是多个呢?
    使用:
weakref.WeakKeyDictionary
weakref.WeakValueDictionary
weakref.WeakSet
  1. 手动使引用计数-1
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值