详细分析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爬虫之urllib2使用指南
Nov 05 Python
Python通过90行代码搭建一个音乐搜索工具
Jul 29 Python
详解Python编程中包的概念与管理
Oct 16 Python
Python numpy 常用函数总结
Dec 07 Python
使用Python进行AES加密和解密的示例代码
Feb 02 Python
Linux下python与C++使用dlib实现人脸检测
Jun 29 Python
Python Pandas中根据列的值选取多行数据
Jul 08 Python
python-tornado的接口用swagger进行包装的实例
Aug 29 Python
python GUI库图形界面开发之PyQt5窗口类QMainWindow详细使用方法
Feb 26 Python
Python常用断言函数实例汇总
Nov 30 Python
教你如何使用Python Tkinter库制作记事本
Jun 10 Python
Python如何加载模型并查看网络
Jul 15 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
php中ob(Output Buffer 输出缓冲)函数使用方法
2007/07/21 PHP
php print EOF实现方法
2009/05/21 PHP
整理的一些实用WordPress后台MySQL操作命令
2013/01/07 PHP
编写php应用程序实现摘要式身份验证的方法详解
2013/06/08 PHP
PHP仿博客园 个人博客(1) 数据库与界面设计
2013/07/05 PHP
简单实用的PHP文本缓存类实例
2019/03/22 PHP
json跟xml的对比分析
2008/06/10 Javascript
javascript 当前日期加(天、周、月、年)
2009/08/09 Javascript
javascript 操作Word和Excel的实现代码
2009/10/26 Javascript
jQuery的强大选择器小结
2009/12/27 Javascript
对字符串进行HTML编码和解码的JavaScript函数
2010/02/01 Javascript
再论Javascript的类继承
2011/03/05 Javascript
Javascript学习笔记之 函数篇(三) : 闭包和引用
2014/11/23 Javascript
jquery中show()、hide()和toggle()用法实例
2015/01/15 Javascript
javascript十六进制及二进制转化的方法
2015/05/06 Javascript
JS输出空格的简单实现方法
2016/09/08 Javascript
ES6实现的遍历目录函数示例
2017/04/07 Javascript
JavaScript实现网页头部进度条刷新
2017/04/16 Javascript
JS实现下拉菜单列表与登录注册弹窗效果
2017/08/10 Javascript
JavaScript多种滤镜算法实现代码实例
2019/12/10 Javascript
python和bash统计CPU利用率的方法
2015/07/10 Python
python实现按行切分文本文件的方法
2016/04/18 Python
Python 列表(List) 的三种遍历方法实例 详解
2017/04/15 Python
对Django中的权限和分组管理实例讲解
2019/08/16 Python
python能做什么 python的含义
2019/10/12 Python
使用Numpy对特征中的异常值进行替换及条件替换方式
2020/06/08 Python
移动端Web页面的CSS3 flex布局快速上手指南
2016/05/31 HTML / CSS
美国摄影爱好者购物网站:Focus Camera
2016/10/21 全球购物
优秀医生事迹材料
2014/02/12 职场文书
售后服务经理岗位职责
2014/02/25 职场文书
购房协议书范本
2014/04/11 职场文书
社区精神文明建设汇报材料
2014/08/17 职场文书
销售区域经理岗位职责
2015/04/10 职场文书
2016八一建军节慰问信
2015/11/30 职场文书
react国际化react-intl的使用
2021/05/06 Javascript