Python 的垃圾回收回收机制(源码)

python内存管理及垃圾回收

1. 引用计数器

1.1 环状双向连表 refchain

在python程序中创建的任何对象都会放在refchain链表中,并且可以通过这个对象访问到上一个和下一个对象。

name = '张三'
age = 18
hobby = ['美女','吃饭']
内部会建立一些数据 -打包 C语言叫做结构体-> 【上一个对象、下一个对象、类型、引用个数】
name = "张三"   # 创建一个对象开辟内存空间
new = name  # new指向指向"张三"这块内存,不会重新分配内存,引用计数+1内部会建立一些数据 【上一个对象、下一个对象、类型、引用个数、val=18】
age = 18   # int会添加具体值内部会建立一些数据 【上一个对象、下一个对象、类型、引用个数、items=元素、元素个数】
hobby = ['美女','吃饭']  # 列表会添加元素和元素个数

C语言源码

  • 每个对象都有相同的值:PyObject 结构体 (4个值)。
  • 有多个元素组成的对象:PyObject 结构体 (4个值) + ob_size 。
#define PyObject_HEAD       PyObject ob_base;
#define PyObject_VAR_HEAD      PyVarObject ob_base;// 宏定义,包含 上一个、下一个,用于构造双向链表。(放到refchain链表中时会用到)
#define _PyObject_HEAD_EXTRA            \struct _object *_ob_next;           \struct _object *_ob_prev;// 结构体
typedef struct _object {_PyObject_HEAD_EXTRA // 用于构造双向链表Py_ssize_t ob_refcnt;  // 引用计数器struct _typeobject *ob_type;    // 数据类型
} PyObject;typedef struct {PyObject ob_base;   // PyObject对象Py_ssize_t ob_size; /* Number of items in variable part,即:元素个数 */
} PyVarObject;

源码解析,包含:

  • 2个结构体
    • PyObject,此结构体中包含3个元素。
      • _PyObject_HEAD_EXTRA,用于构造双向链表。
      • ob_refcnt,引用计数器。
      • *ob_type,数据类型。
    • PyVarObject,次结构体中包含4个元素(ob_base中包含3个元素)
      • ob_base,PyObject结构体对象,即:包含PyObject结构体中的三个元素。
      • ob_size,内部元素个数。
  • 3个宏定义
    • PyObject_HEAD,代指PyObject结构体。
    • PyVarObject_HEAD,代指PyVarObject对象。
    • _PyObject_HEAD_EXTRA,代指前后指针,用于构造双向队列。

1.2 不同类型封装的结构体

# float类型
data = 3.14内部会创建:_ob_next = refchain 中的上一个对象_ob_prev = refchain 中的下一个对象 ob_refcnt = 1 ob_type = floatob_fval = 3.14

C源码:

typedef struct {PyObject_HEADdouble ob_fval;
} PyFloatObject;

1.3 引用计数器

v1 = 3.14
v2 = 999
v3 = [1,2,3]

当python程序运行时,会根据数据类型的不同找到其对应的结构体,根据结构体中的字段进行创建相关的数据,然后将对象添加到refchain双向链表中。

在C源码中有两个关键的结构体:PyObject、PyVarObject。

每个对象中有ob_refcnt 就是引用计数器,默认值为1,当有其他变量引用对象时,引用计数器就会发生变化。

  • 引用

    a = 999
    b = a    # 999 这个对象的引用计数器+1,为2
    
  • 删除引用

    a = 999
    b = a 
    del b  # b变量删除,b对应的对象的引用计数器 -1
    del a  # a变量删除,a对应的对象的引用计数器 -1 (a、b对应同一个对象)"""
    当一个对象的引用计数器为0时,意味着没有人可以使用这个对象了,这个对象就是垃圾,需要被回收
    回收:1.对象从refchain链表中移除2.将对象销毁,内存归还系统"""
    

    1.5 循环引用

在这里插入图片描述

2. 标记清除

目的:为了解决引用计数器循环引用的不足。

实现:在python的底层 再维护一个链表,链表中专门放那些可能存在循环引用的对象 (list/tuple/dict/set)。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-V9eqdYfm-1605967623655)(E:\07-notes\picture\57_解决循环引用图.png)]在这里插入图片描述

在python内部 某种情况下 触发,会去扫描 可能存在循环引用的链表中的每一个元素,检查是否有循环引用,如果有则双方的引用计数器 -1,如果是 0 则垃圾回收。

问题:

  • 什么时候扫描?
  • 可能存在循环引用的链表扫描代价较大,每次扫描耗时久。

3. 分代回收

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-K55asNPj-1605967623657)(E:\07-notes\picture\58_分待回收图在这里插入图片描述
.png)]

将可能存在循环引用的对象维护成 3个链表:

  • 0代:0代中对象个数达到700个扫描一次;
  • 1代:0代扫描 10 次,则 1代扫描一次;
  • 2代:1代扫描10次,则 2 代扫描一次。

4. 小结

在python中维护了一个refchain的双向环状链表,这个链表中存储程序中创建的所有对象,每种类型的对象都有一个 ob_refcnt 的引用计数器的值,对象被引用,则计数器的值 +1,引用被删除则计数器的值 -1,最后引用计数的值为 0 时,会进行垃圾回收(对象销毁、从refchain中移除),

但是,在python中对于那些可以有多个元素组成的对象可能会存在循环引用问题,为了解决这个问题python引入了 标记清除 ,在其内部再维护了一个链表,专门放那些可能存在循环引用的对象 (list/tuple/dict/set), 某种情况下 触发,会去扫描 可能存在循环引用的链表中的每一个元素,检查是否有循环引用,如果有则双方的引用计数器 -1,如果是 0 则垃圾回收,

然而,又有一个新的问题产生,就是什么时候扫描?可能存在循环引用的链表扫描代价较大,每次扫描耗时久,所以又引入了 分代回收 ,将可能存在循环引用对象维护成 3 个链表,分别是 0代,1代,2代,所有可能存在循环引用的对象都存储在 0代链表,当对象个数达到700个的时候扫描一次,是垃圾则回收,不是则移代 1代,依次类推,0代扫描10次,1代扫描一次,1代扫描10次,2代扫描1次。

e=5>分代回收 ,将可能存在循环引用对象维护成 3 个链表,分别是 0代,1代,2代,所有可能存在循环引用的对象都存储在 0代链表,当对象个数达到700个的时候扫描一次,是垃圾则回收,不是则移代 1代,依次类推,0代扫描10次,1代扫描一次,1代扫描10次,2代扫描1次。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/491950.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

未来五年人工智能将实现的五大突破

来源:资本实验室不论是可以和你对话的智能音箱,还是能够自己作画的虚拟艺术家;不论是能够帮助农民准确判断种植和施肥时间的农场管理系统,又或者是能够在演唱会现场快速识别罪犯的人脸识别程序,人工智能已经开始在各行…

python面试常问

一、Python基础部分 1. 数据类型 数字类型(Numbers): 整数(int), 浮点数(float), 复数(complex) 布尔(Booleans): True和False 字符串(Str):Uniconde字符序列, 在引号内包含 列表(list): 有序的值的序列 元组(Tuples)&#x…

springJDBC一对多关系,以及Java递归,jsp递归的实现

maven编译,springMVCspringspringJDBC框架。 要实现的功能是一个文件夹下,可能显示n个文件夹,每个文件夹下又可能显示n个文件夹。。。。 前台效果: controller中的方法如下: RequestMapping(value"/index",m…

未来全球15大热门研究方向出炉!

转自:科学网(sciencenet-cas)要点速览伦敦、纽约、新加坡、香港、巴黎、北京、东京、迪拜、上海、柏林、波士顿,这些国际性大都市在科技创新方面的表现如何?它们主要关注哪些研究方向?15大科技创新策源点&a…

Django-rest framework

Django-rest Framework 1. FBV CBV 1.1 开发模式 普通开发方式(前后端放在一起写)前后端分离 1.2 后端开发 为前端提供URL(API/接口的开发) 注:永远返回HttpResponse 1.3 Django FBV、CBV # FBV(function base …

常用的网络营销方法有哪些

索引擎营销 电子邮件营销 即时通讯营销 病毒式营销 BBS营销 博客营销 播客营销 RSS营销 SN营销 创意广告营销 知识型营销 事件营销 口碑营销 转载于:https://www.cnblogs.com/happyday56/p/4739488.html

AI产业链分布图曝光:1040个玩家,BAT率先步入应用

来源:网络大数据5月9日,在苏州举办的全球人工智能产品应用博览会上,《新一代人工智能发展年度报告(2018)》重磅发布。发布方是中国经济信息社与新一代人工智能产业技术创新战略联盟。报告相当于对2018年以来全球AI领域融资、国内AI企业分布、…

什么是混合云?

来源:光联集团混合云是使那些正常的进化措施看起来更酷,是IT前沿术语之一。亚马逊,谷歌和微软等云供应商倡导企业关闭内部数据中心并将所有基础架构迁移到云端,这就是“超融合”数据中心战略。1转移基础设施对于刚刚起步的公司而言…

Shell—grep、sed、awk

Shell学习 Shell 是一个用 C 语言编写的程序,它是用户使用 Linux 的桥梁。Shell 既是一种命令语言,又是一种程序设计语言。 Shell 是指一种应用程序,这个应用程序提供了一个界面,用户通过这个界面访问操作系统内核的服务。 She…

【科普】AI的分类与演进

来源:物联网智库摘要:AI是人工通过高强度的计算能力,并基于大量的环境数据、行为数据、历史数据等大数据支持,或是一定规则的自学习机制,来分析特定输入的情况下,事物的相关性、影响和可能处理方法&#xf…

AngularJs入门学习

http://www.ituring.com.cn/article/13471 安装并配置好所有依赖环境之后,只需要在cmd进入angular-phonecat目录。接着指令操作npm start;开启服务器。如下图: 打开angular-phonecat的gitbash; 接下来就是用编译器打开angular-pho…

nginx+uWSGI + django部署项目

项目部署 nginxuWSGI django 1. WSGI WSGI是Web服务器网关接口。它是一个规范,描述了Web服务器(返回静态资源的就是web服务器,Nginx)如何与Web应用程序(django、Flask)通信,以及Web应用程序如何链接在一起以处理一个请求,&…

71页《乌镇智库:全球人工智能发展报告(2018)》PDF下载

来源:专知【导读】人工智能热潮之下,斯坦福、阿里等纷纷出台人工智能报告。乌镇智库已连续发布三年《全球人工智能发展报告》,以宏观视角纵览全球人工智能发展,从产业、融资、技术、教育和应用等多个角度展现人工智能在全球的发展…

Windows实用技巧

Windows常用命令,亲测可用 创建文件夹Test,命令为:mkdir Test 盘符: 进入系统中的某个盘,例如E:进入E盘cd 文件夹位置 进入某个文件夹,需要先进入盘符,即完成第一步,例如…

python进程、线程、协程

通过学习bi站 蚂蚁学Python 老师视频总结文档,仅用于学习。。。 python进程、线程、协程 多线程:threading,利用CPU和IO可以同时执行的原理,不会让CPU干巴巴的等待IO完成 多进程:multiprocessing,利用多核…

一文读懂计算计仿真技术

来源:传感器技术计算机仿真作为分析和研究系统运行行为、揭示系统动态过程和运动规律的一种重要手段和方法, 随着系统科学研究的深入、控制理论、计算技术、计算机科学与技术的发展而形成的一门新兴学科。近年来, 随着信息处理技术的突飞猛进, 使仿真技术得到迅速发…

Chrome Cookie SameSite 属性设置

Chrome Cookie SameSite 设置 Chrome 51 开始,浏览器的 Cookie 新增加了一个SameSite属性,用来防止 CSRF 攻击和用户追踪。 Cookie 的SameSite属性用来限制第三方 Cookie,从而减少安全风险。 它可以设置三个值。 StrictLaxNone Chrome 默认…

胡蜂也会逻辑推理

胡蜂能通过基本的逻辑测试。来源: 中国科学报逻辑推理是一种复杂的行为,通常被认为仅限于具有复杂神经系统的动物。但一项新的研究表明,胡蜂可以运用某种逻辑推理。这在无脊椎动物中尚属首次。相关成果日前发表于英国《皇家学会生物学报》。这…

二十大未来最有潜力的新材料(绝对经典值得收藏)

来源:新材料在线石墨烯、碳纳米管、非晶合金、泡沫金属、离子液体……20种新材料,为材料工业工业发展带来无限机遇。材料工业是国民经济的基础产业,新材料是材料工业发展的先导,是重要的战略性新兴产业。今天,科技革命…

Unity3D 4.x 使用Mecanim实现动画控制

Unity3D 4.x 版本号之后提供了一种新的动画机制Mecanim,尽管眼下还支持之前的Animation。但看到Unity3D 4.3 预览版里Sprite的动画也是基于Animator的,可知Mecanim将会是以后动画播放的趋势! Mecanim是一种基于状态机的结构,不同的…