在python中的垃圾回收机制主要是以引用计数为主要手段以标记清除和隔代回收机制为辅的手段 。可以对内存中无效数据的自动管理!在这篇文章,带着这个问题来一直往下看:怎么知道一个对象能不能被调用了呢?
创新互联长期为上1000+客户提供的网站建设服务,团队从业经验10年,关注不同地域、不同群体,并针对不同对象提供差异化的产品和服务;打造开放共赢平台,与合作伙伴共同营造健康的互联网生态环境。为桓仁企业提供专业的做网站、网站设计,桓仁网站改版等技术服务。拥有10年丰富建站经验和众多成功案例,为您定制开发。
回顾内存地址
Python中的任何变量都有对应的内存引用,也就是内存地址。
如果不是容器类型,那么直接引用和赋值,内存地址都是不会的。
- >>> a = 1
- >>> b = 1
- >>> id(a)
- 140709385600544
- >>> id(b)
- 140709385600544
如果在内存中创建了一个list对象(容器),而且对该对象进行了引用。那么b = [1,2]和c = a有什么区别?
- >>> a = [1,2]
- >>> b = [1,2]
- >>> id(a)
- 1966828025736
- >>> id(b)
- 1966828044488
- >>> c = a
- >>> id(c)
- 1966828025736
首先在内存1966828025736处创建了一个列表 [1,2],然后定义了一个名为a的变量。b = [1,2]会新开一个内存地址,c = a直接赋值直接引用[1,2]的内存地址。
引用计数
在一些代码中,如果存在一些变量但是没有用,会造成内存空间,因此叫做垃圾,所以要回收。
引用计数也是一种最直观,最简单的垃圾收集技术。原理非常简单,每一个对象都包含了两个头部信息,一个是类型标志符,标识这个对象的类型;另一个是计数器,记录当前指向该对象的引用数目,表示这个对象被多少个变量名所引用。
CPython 使用引用计数来管理内存,所有 Python 脚本中创建的实例,都会有一个引用计数,来记录有多少个指针指向它。当引用计数只有 0 时,则会自动释放内存。
在Python中通过sys.getrefcount查看引用计数的方法,
- print(sys.getrefcount())
注意调用getrefcount()函数会临时增加一次引用计数,得到的结果比预期的多一次。
比如,下面这个例子中,a 的引用计数是 3,因为有 a、b 和作为参数传递的 getrefcount 这三个地方,都引用了一个空列表。
- >>> import sys
- >>> a = []
- >>> b = a
- >>> print(sys.getrefcount(a))
- 3
我们通过一些例子来看下,可以使python对象的引用计数增加或减少的场景。
- import sys
- a = []
- # 两次引用,一次来自 a,一次来自 getrefcount
- print(sys.getrefcount(a))
- def func(a):
- # 四次引用,a,python 的函数调用栈,函数参数,和 getrefcount
- print(sys.getrefcount(a))
- func(a)
- # 两次引用,一次来自 a,一次来自 getrefcount,函数 func 调用已经不存在
- print(sys.getrefcount(a))
- ########## 输出 ##########
- 2
- 4
- 2
引用计数是用来记录对象被引用的次数,每当对象被创建或者被引用时将该对象的引用次数加一,当对象的引用被销毁时该对象的引用次数减一,当对象的引用次数减到零时说明程序中已经没有任何对象持有该对象的引用,换言之就是在以后的程序运行中不会再次使用到该对象了,那么其所占用的空间也就可以被释放了了。
计数增加和减少
下面引用计数增加的场景:
引用计数减少的场景:
- import sys
- def ref_method(str):
- print(sys.getrefcount(str))
- print("我调用了{}".format(str))
- print('方法执行完了')
- def ref_count():
- # 引用计数增加的场景
- print('测试引用计数增加')
- a = 'A'
- print(sys.getrefcount(a))
- b = a
- print(sys.getrefcount(a))
- ref_method(a)
- print(sys.getrefcount(a))
- c = [1, a, 'abc']
- print(sys.getrefcount(a))
- # 引用计数减少的场景
- print('测试引用计数减少')
- del b
- print(sys.getrefcount(a))
- c.remove(a)
- print(sys.getrefcount(a))
- del c
- print(sys.getrefcount(a))
- a = 783
- print(sys.getrefcount(a))
- if __name__ == '__main__':
- ref_count()
- ########## 输出 ##########
- 测试引用计数增加
- 78 #77+1 77在函数中是随机的
- 79
- 81
- 我调用了A
- 方法执行完了
- 79
- 80
- 测试引用计数减少
- 79
- 78
- 78
- 4
本文已收录 GitHub,传送门~[2] ,里面更有大厂面试完整考点,欢迎 Star。
文章标题:深入Python中引用计数
当前网址:http://www.mswzjz.cn/qtweb/news16/246816.html
攀枝花网站建设、攀枝花网站运维推广公司-贝锐智能,是专注品牌与效果的网络营销公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 贝锐智能