详细分析Python垃圾回收机制


Posted in Python onJuly 01, 2020

引入

为什么要有垃圾回收机制

Python中的垃圾回收机制简称(GC),我们在程序的运行中会产生大量的变量用于保存数据,而有时候有些变量已经没有用了就需要被清理释放掉该变量所占据的内存空间。在一些较为低级的语言中(比如:C语言,汇编语言)对于内存空间的释放是需要编程人员来手动进行的,这种与底层硬件直接打交道的操作是十分的危险与繁琐的,而基于C语言开发而来的Python为了解决掉这种顾虑则自带了一种垃圾回收机制,从而让开发人员不必过分担心内存的使用情况而可以全身心的投入到开发中去。

>>> name = "yunya" #yunya 准备改名
>>> name = "yunyaya" #原本yunya这个名字不使用了,现在必须清理掉它否则将会占据内存空间,所幸Python的垃圾回收机制会帮我清理掉 "yunya"
>>

堆区和栈区的概念

如果你看我之前写的那篇文章关于Python变量的底层原理的话那么想必对堆区和栈区内存有了一定的了解。如果没有看过那么也没有关系,链接如下:

底层工作原理

引用计数

引用计数说白了就是来对堆区的变量值绑定的栈区变量名来计数。如图:

详细分析Python垃圾回收机制

当使用del或者对变量名重新赋值后,该变量值的引用计数就会 -1 。当引用计数为 0 时候下次 Python内存回收机制 进行内存扫描时便会将该变量值当做垃圾进行回收。

详细分析Python垃圾回收机制

 那么这里就是Python内存回收机制中最基本的也最常用的引用计数介绍。

循环引用-内存泄漏

引用计数虽然作为Python内存回收机制中最经常使用的一种机制,但是它本身也是具有一定的缺点。我们来看下面这段代码:

>>> l1 = [1,2,3]
>>> l2 = [1,2,3,l1]
>>> l1.append(l2)  #append()方法用于向列表中添加一个元素值
>>> l1
[1, 2, 3, [1, 2, 3, [...]]]
>>> l2
[1, 2, 3, [1, 2, 3, [...]]]
>>>

现在l1和l2全部作为互相引用了。那么对于这种引用方式叫做循环引用(也被称为交叉引用),循环引用会带来一个问题:

  1. l1 变量值 的引用计数 目前为 2
  2. l2 变量值 的引用计数 目前为 2
  3. 当使用 del l1 与 del l2 后呢?
  4. 它们的引用变量都减1,但是引用方式的变量名都互相删除了,按理说这些变量值都成了垃圾变量。单根据引用计数是无法清理这些垃圾变量的。

 详细分析Python垃圾回收机制

>>> del l1
>>> del l2
>>> #现在怎么访问 li1 或者 li2 呢?访问不到,但是他们的变量值依然存在于内存,引用计数从2变为1

标记-清除

标记清除的意思在于当应用程序可用内存空间即将被耗尽时便开始扫描栈区,并且会顺着栈区变量名对堆区中的变量值做一个标记,如果堆区中存在没有与栈区变量名做对应关系的数据则会被认为是垃圾数据从而被Python垃圾回收机制清理。

详细分析Python垃圾回收机制

效率问题解决方案-分代回收

基于引用计数的垃圾回收机制每一次执行清理操作前都会将整个堆区的变量值的引用计数做一次遍历统计。这样做是非常消耗时间的,所以Python垃圾回收机制为了效率的提升加入了分代回收的策略。

详细分析Python垃圾回收机制

参考文献

以上就是详细分析Python垃圾回收机制的详细内容,更多关于Python垃圾回收机制的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
python常规方法实现数组的全排列
Mar 17 Python
python访问系统环境变量的方法
Apr 29 Python
python实现的简单抽奖系统实例
May 22 Python
python如何让类支持比较运算
Mar 20 Python
Python实现删除时保留特定文件夹和文件的示例
Apr 27 Python
Python爬虫实现全国失信被执行人名单查询功能示例
May 03 Python
Python中的元组介绍
Jan 28 Python
Python常用爬虫代码总结方便查询
Feb 25 Python
6行Python代码实现进度条效果(Progress、tqdm、alive-progress​​​​​​​和PySimpleGUI库)
Jan 06 Python
python使用numpy实现直方图反向投影示例
Jan 17 Python
Tensorflow的梯度异步更新示例
Jan 23 Python
python使用多线程查询数据库的实现示例
Aug 17 Python
Python自带的IDE在哪里
Jul 01 #Python
如何解决cmd运行python提示不是内部命令
Jul 01 #Python
python中执行smtplib失败的处理方法
Jul 01 #Python
解决Keras的自定义lambda层去reshape张量时model保存出错问题
Jul 01 #Python
完美解决keras 读取多个hdf5文件进行训练的问题
Jul 01 #Python
学python需要去培训机构吗
Jul 01 #Python
详解python logging日志传输
Jul 01 #Python
You might like
DC漫画《蝙蝠侠和猫女》图透 猫女怀孕老爷当爹
2020/04/09 欧美动漫
用PHP制作静态网站的模板框架(三)
2006/10/09 PHP
PHPnow安装服务[apache_pn]失败的问题的解决方法
2010/09/10 PHP
ThinkPHP的I方法使用详解
2014/06/18 PHP
PHP获取服务器端信息的方法
2014/11/28 PHP
CI(Codeigniter)的Setting增强配置类实例
2016/01/06 PHP
php语言的7种基本的排序方法
2020/12/28 PHP
php简单的上传类分享
2016/05/15 PHP
PHP实现驼峰样式字符串(首字母大写)转换成下划线样式字符串的方法示例
2017/08/10 PHP
PHP多进程简单实例小结
2019/11/09 PHP
ThinkPHP 框架实现的读取excel导入数据库操作示例
2020/04/14 PHP
二级域名转向类
2006/11/09 Javascript
jquery蒙版控件实现代码
2010/12/08 Javascript
js实现按Ctrl+Enter发送效果
2014/09/18 Javascript
Bootstrap表单布局样式代码
2016/05/31 Javascript
JavaScript中windows.open()、windows.close()方法详解
2016/07/28 Javascript
javascript之IE版本检测超简单方法
2016/08/20 Javascript
基于substring()和substr()的使用以及区别(实例讲解)
2017/12/28 Javascript
原生JS实现列表内容自动向上滚动效果
2019/05/22 Javascript
详解vue父子组件关于模态框状态的绑定方案
2019/06/05 Javascript
React Ant Design树形表格的复杂增删改操作
2020/11/02 Javascript
Vue中使用wangeditor富文本编辑的问题
2021/02/07 Vue.js
[42:22]DOTA2上海特级锦标赛C组小组赛#1 OG VS Archon第一局
2016/02/27 DOTA
[48:05]2018DOTA2亚洲邀请赛 3.31 小组赛 B组 VGJ.T vs VP
2018/03/31 DOTA
python标准日志模块logging的使用方法
2013/11/01 Python
python 实现矩阵按对角线打印
2019/11/29 Python
Python:二维列表下标互换方式(矩阵转置)
2019/12/02 Python
基于YUV 数据格式详解及python实现方式
2019/12/09 Python
python中元组的用法整理
2020/06/15 Python
关于django python manage.py startapp 应用名出错异常原因解析
2020/12/15 Python
全球采购的街头服饰和帽子:Urban Excess
2020/10/28 全球购物
大学生就业协议书范本(适用于公司企业)
2014/10/07 职场文书
2014法制宣传日活动总结范文
2014/11/01 职场文书
音乐教师个人工作总结
2015/02/06 职场文书
Go 中的空白标识符下划线
2022/03/25 Golang
Python+Pillow+Pytesseract实现验证码识别
2022/05/11 Python