当前位置: 首页 > news >正文

Python开发运维:Python垃圾回收机制

目录

一、理论

1.Python垃圾回收机制




一、理论

1.Python垃圾回收机制

(1)引⽤计数器

1)环状双向链表 refchain
在python程序中创建的任何对象都会放在refchain链表中。

name = "david"
age = 20
hobby = ["篮球",'游泳']
内部会创建⼀些数据【 上⼀个对象、下⼀个对象、类型、引⽤个数 】
name = "david"
new = name内部会创建⼀些数据【 上⼀个对象、下⼀个对象、类型、引⽤个数、val=18】
age = 20内部会创建⼀些数据【 上⼀个对象、下⼀个对象、类型、引⽤个数、items=元素、元素个数 】
hobby = ["篮球",'游泳']


在C源码中如何体现每个对象中都有的相同的值:PyObject结构体(4个值)。
有多个元素组成的对象:PyObject结构体(4个值) + ob_size 。

2)类型封装结构体

data = 3.14内部会创建:_ob_next = refchain中的上⼀个对象_ob_prev = refchain中的下⼀个对象ob_refcnt = 1ob_type = floatob_fval = 3.14

3)引⽤计数器

v1 = 3.14
v2 = 999
v3 = (1,2,3)

当python程序运⾏时,会根据数据类型的不同找到其对应的结构体,根据结构体中的字段来进⾏创建相 关的数据,然后将对象添加到refchain双线链表中。 在C源码中有两个关键的结构体:PyObject、PyVarObject。 每个对象中有 ob_refcnt就是引⽤计数器,值默认为 1 ,当有其他变量引⽤对象时,引⽤计数器就会发 ⽣变化。

#引⽤
a = 777
b = a#删除引⽤
a = 777
b = a
del b # b变量删除;b对应对象引⽤计数器-1
del a # a变量删除;a对应对象引⽤计数器-1
# 当⼀个对象的引⽤计数器为0时,意味着没有⼈再使⽤这个对象了,这个对象就是垃圾,垃圾回收。
# 回收:1.对象从refchain链表移除;2.将对象销毁,内存归还。

4)循环引⽤问题

v1 = [11,22,33]  #refchain中创建一个列表对象,由于v1=对象,所以列表引用对象计数器为1
v2 = [44,55,66]  #refchain中创建一个列表对象,由于v2=对象,所以列表引用对象计数器为1
v1.append(v2)    #把v2追加到v1中,则v2对应的[44,55,66]对象的引用计数器增加1,最终为2
v2.append(v1)    #把v1追加到v2中,则v1对应的[11,22,33]对象的引用计数器增加1,最终为2del v1           #引用计数器-1
del v2           #引用计数器-1

(2)标记清除

⽬的:为了解决引⽤计数器循环引⽤的不⾜。
实现:在python的底层再维护⼀个链表,链表中专⻔放那些可能存在循环引⽤的对象
(list/tuple/dict/set)。

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

(3)分代回收

将可能存在循环应⽤的对象维护成3个链表:
0代:0代中对象个数达到700个扫描⼀次。
1代:0代扫描10次,则1代扫描⼀次。
2代:1代扫描10次,则2代扫描⼀次。

(4) 总结

在python中维护了⼀个refchain的双向环状链表,这个链表中存储程序创建的所有对象,每种类型的对
象中都有⼀个ob_refcnt引⽤计数器的值,引⽤个数 + 1、-1 ,最后当引⽤计数器变为0时会进⾏垃圾回
收(对象销毁、refchain中移除)。但是,在python中对于那些可以有多个元素组成的对象可能会存在循环引⽤的问题,为了解决这个问题
python⼜引⼊了标记清除和分代回收,在其内部为了4个链表,
refchain
2代,10⼨
1代,10次
0代,700个在源码内部当达到各⾃的阈值时,就会触发扫描链表进⾏标记清除的动作(有循环则各⾃-1)。

http://www.lryc.cn/news/255895.html

相关文章:

  • ros2/ros安装ros-dep||rosdep init错误
  • 《深入理解计算机系统》学习笔记 - 第四课 - 机器级别的程序
  • 云原生(Cloud Native)——概念,技术,背景,优缺点,实践例子
  • ElasticSearch之线程池
  • StoneDB-8.0-V2.2.0 企业版正式发布!性能优化,稳定性提升,持续公测中!
  • 【数据结构 — 排序 — 插入排序】
  • 物联网后端个人第十四周总结
  • 在uniapp中,可以使用那些预定义的样式类
  • mybatis的数据库连接池
  • Vue 的 el-select 下拉选项中,只有当文字超出时才显示提示框,未超出的则不显示
  • 【Python】pptx文件转pdf
  • response应用及重定向和request转发
  • CentOS常用基础命令大全(linux命令)2
  • 分析阿里巴巴的微服务依赖图和性能
  • Linux——基本指令(一)
  • 虚幻学习笔记10—C++函数与蓝图的通信
  • 无重复字符的最长子串(LeetCode 3)
  • 交付《啤酒游戏经营决策沙盘》的项目
  • 油猴(Tampermonkey)浏览器插件简单自定义脚本开发
  • BGP综合
  • 库函数qsort的使用及利用冒泡排序模拟实现qsort
  • mybatis和mybatisplus中对 同namespace 中id重复处理逻辑源码解析
  • linux下部署frp客户端服务端-内网穿透
  • Markdown to write
  • ResNeXt(2017)
  • DreamPlace 的下载安装与使用
  • FPGA模块——SPI协议(读写FLASH)
  • SQL自学通之表达式条件语句与运算
  • 公网域名如何解析到内网IP服务器——快解析域名映射外网访问
  • 线程安全与并发区别