详细分析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 相关文章推荐
pyramid配置session的方法教程
Nov 27 Python
python进程类subprocess的一些操作方法例子
Nov 22 Python
在Python的Flask框架中使用模版的入门教程
Apr 20 Python
在Python程序中进行文件读取和写入操作的教程
Apr 28 Python
python中日志logging模块的性能及多进程详解
Jul 18 Python
pandas全表查询定位某个值所在行列的方法
Apr 12 Python
python f-string式格式化听语音流程讲解
Jun 18 Python
python实现大学人员管理系统
Oct 25 Python
windows中安装Python3.8.0的实现方法
Nov 19 Python
python3.x 生成3维随机数组实例
Nov 28 Python
Django Admin设置应用程序及模型顺序方法详解
Apr 01 Python
LeetCode189轮转数组python示例
Aug 05 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
网站加速 PHP 缓冲的免费实现方法
2006/10/09 PHP
Godaddy空间Zend Optimizer升级方法
2010/05/10 PHP
PHP函数篇详解十进制、二进制、八进制和十六进制转换函数说明
2011/12/05 PHP
php恢复数组的key为数字序列的方法
2015/04/28 PHP
php中header跳转使用include包含解决参数丢失问题
2015/05/08 PHP
php利用smtp类实现电子邮件发送
2015/10/30 PHP
我见过最全的个人js加解密功能页面
2007/12/12 Javascript
Jquery为单选框checkbox绑定单击click事件
2012/12/18 Javascript
ajax+jQuery实现级联显示地址的方法
2015/05/06 Javascript
让JavaScript中setTimeout支持链式操作的方法
2015/06/19 Javascript
关于JS中prototype的理解
2015/09/07 Javascript
Javascript控制div属性动态变化实例分析
2015/10/08 Javascript
JS实现网页游戏中滑块响应鼠标点击移动效果
2015/10/19 Javascript
全面解析Bootstrap图片轮播效果
2015/12/03 Javascript
js时间戳转为日期格式的方法
2015/12/28 Javascript
JavaScript判断变量是否为数组的方法(Array)
2016/02/24 Javascript
JS hashMap实例详解
2016/05/26 Javascript
jQuery EasyUI datagrid在翻页以后仍能记录被选中行的实现代码
2016/08/15 Javascript
JS实现碰撞检测的方法分析
2018/01/19 Javascript
vue.js与后台数据交互的实例讲解
2018/08/08 Javascript
使用ESLint禁止项目导入特定模块的方法步骤
2019/03/04 Javascript
vue 点击展开显示更多(点击收起部分隐藏)
2019/04/09 Javascript
Python 序列化 pickle/cPickle模块使用介绍
2014/11/30 Python
python中hashlib模块用法示例
2017/10/30 Python
Python中那些 Pythonic的写法详解
2019/07/02 Python
浅谈PyQt5中异步刷新UI和Python多线程总结
2019/12/13 Python
python利用百度云接口实现车牌识别的示例
2020/02/21 Python
python交互模式基础知识点学习
2020/06/18 Python
详解HTML5中download属性的应用
2015/08/06 HTML / CSS
伦敦高级内衣品牌:Agent Provocateur(大内密探)
2016/08/23 全球购物
菲律宾最大的网上花店和礼品店:PhilFlower.com
2018/02/09 全球购物
Agoda台湾官网:国内外订房2折起
2018/03/20 全球购物
开学典礼观后感
2015/06/15 职场文书
Windows下使用Nginx+Tomcat做负载均衡的完整步骤
2021/03/31 Servers
Mysql MVCC机制原理详解
2021/04/20 MySQL
css3 利用transform-origin 实现圆点分布在大圆上布局及旋转特效
2021/04/29 HTML / CSS