详细分析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修改注册表终止360进程实例
Oct 13 Python
python设置值及NaN值处理方法
Jul 03 Python
在Python中通过getattr获取对象引用的方法
Jan 21 Python
Python从文件中读取数据的方法讲解
Feb 14 Python
OpenCV-Python 摄像头实时检测人脸代码实例
Apr 30 Python
浅析Python与Mongodb数据库之间的操作方法
Jul 01 Python
python爬虫 execjs安装配置及使用
Jul 30 Python
pandas DataFrame行或列的删除方法的实现示例
Aug 02 Python
Python3使用xml.dom.minidom和xml.etree模块儿解析xml文件封装函数的方法
Sep 23 Python
django数据模型(Model)的字段类型解析
Dec 25 Python
Kears 使用:通过回调函数保存最佳准确率下的模型操作
Jun 17 Python
python装饰器三种装饰模式的简单分析
Sep 04 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获取链表中倒数第K个节点的方法
2018/01/18 PHP
laravel返回统一格式错误码问题
2019/11/04 PHP
javascript高亮效果的二种实现方法
2008/09/14 Javascript
firefox插件Firebug的使用教程
2010/01/02 Javascript
Jquery 切换不同图片示例代码
2013/12/05 Javascript
快速解决jQuery与其他库冲突的方法介绍
2014/01/02 Javascript
js选择并转移导航菜单示例代码
2014/08/19 Javascript
JS实现具备延时功能的滑动门菜单效果
2015/09/17 Javascript
浅析JS动态创建元素【两种方法】
2016/04/20 Javascript
jQuery给div,Span, a ,button, radio 赋值与取值
2016/06/24 Javascript
jQuery实现判断控件是否显示的方法
2017/01/11 Javascript
vue2组件实现懒加载浅析
2017/03/29 Javascript
详解Node中导入模块require和import的区别
2017/08/11 Javascript
详解使用jQuery.i18n.properties实现js国际化
2018/05/04 jQuery
js for终止循环 跳出多层循环
2018/10/04 Javascript
vue双向绑定数据限制长度的方法
2019/11/04 Javascript
基于NodeJS开发钉钉回调接口实现AES-CBC加解密
2020/08/20 NodeJs
python中的闭包用法实例详解
2015/05/05 Python
python实现爬取千万淘宝商品的方法
2015/06/30 Python
Python使用当前时间、随机数产生一个唯一数字的方法
2017/09/18 Python
Tensorflow加载预训练模型和保存模型的实例
2018/07/27 Python
用python3教你任意Html主内容提取功能
2018/11/05 Python
Python实现账号密码输错三次即锁定功能简单示例
2019/03/29 Python
利用pyinstaller打包exe文件的基本教程
2019/05/02 Python
Python中遍历列表的方法总结
2019/06/27 Python
pip安装python库的方法总结
2019/08/02 Python
python使用hdfs3模块对hdfs进行操作详解
2020/06/06 Python
Python入门基础之数字字符串与列表
2021/02/01 Python
英国领先的汽车轮胎和快速健康中心:Kwik Fit
2017/10/29 全球购物
美国销售第一的智能手机和平板电脑保护壳:OtterBox
2017/12/21 全球购物
电子专业求职信
2014/06/19 职场文书
2015年小学生国庆节演讲稿
2015/07/30 职场文书
2019年暑期法院实习报告
2019/12/18 职场文书
Mysql数据库中datetime、bigint、timestamp来表示时间选择,谁来存储时间效率最高
2021/08/23 MySQL
mysql数据插入覆盖和时间戳的问题及解决
2022/03/25 MySQL
零基础学java之循环语句的使用
2022/04/10 Java/Android