Python的垃圾回收机制详解


Posted in Python onAugust 28, 2019

引用计数

在Python源码中,每一个对象都是一个结构体表示,都有一个计数字段。

typedef struct_object {
  int ob_refcnt;
  struct_typeobject *ob_type;
} PyObject;

PyObject是每个对象必有的内容,其中ob_refcnt就是作为引用计数。当一个对象有了新的引用时,它的ob_refcnt就会增加,引用它的对象被删除时则减少。一旦对象的引用计数为0,该对象立即被回收,占用空间就会被释放。

优点

  • 简单易用
  • 实时性好,一旦没有引用就会被立即释放

缺点

  • 需要额外空间去维护引用计数
  • 不能解决对象的循环引用

对象的循环引用
循环引用是指两个对象相互引用且没有外部变量引用其中任何一个,导致引用链形成一个环。

>>> a = {}    # 对象a的引用计数为1
>>> b = {}    # 对象b的引用计数为1
>>> a['b'] = b  # b的引用计数增加1
>>> b['a'] = a  # a的引用计数增加1
>>> del a     # a的引用计数减少1,最后a的引用为1
>>> del b     # b的引用计数减少1,最后b的引用为1

在执行完del操作之后,没有任何引用指向a、b对象,但是由于这两个对象各自包含一个对对方的引用,所以引用计数始终保持在1。

按照引用计数中内存回收的原理,由于a和b的计数不为0,所以在使用引用计数法进行内存管理的时候这两个对象不会被回收,它们会一直驻留在内存中,造成内存泄露。

标记清除

标记清除机制主要用于解决循环引用问题。

标记清除算法是一种基于追踪回收(tracing GC)技术实现的垃圾回收算法。主要分为两个阶段:

  • 标记阶段,GC会将所有的活动对象打上标记
  • 对那些没有打上标记的非活动对象进行回收

区分活动对象与非活动对象

对象之间通过引用即指针连接在一起,构成一个有向图,对象就是这个有向图的节点,而引用关系构成这个有向图的边。从根对象(root object)出发,沿着有向边遍历对象,可达的对象会被标记为活动对象,不可达的对象就是要被清除的非活动对象。

根对象一般是全局变量、调用栈、寄存器等。

适用范围

标记清除算法作为Python辅助的垃圾收集技术,主要处理的是容器对象,因为对于字符串、数值对象等,不可能造成循环引用的问题,Python会使用一个双向链表将这些容器对象组织起来。

对于标记清除算法来说,有一个比较明显的缺点:为了清除非活动对象,需要扫描整个堆内存,哪怕只剩下小部分活动对象也需要扫描所有对象。

分代回收

分代回收是一种以空间换时间的操作方式,建立在标记清除技术的基础之上,也是Python辅助的垃圾收集技术,主要用于处理容器对象。

Python会将内存根据对象的存活时间划分为不同的集合,每个集合称为一个代,主要会被分为3代:年轻代。中年代和老年代,它们会对应3个链表,对应的垃圾收集频率随着对象存活时间的增大而减小。

新创建的对象都会被分配在年轻代,当年轻代链表总数达到上限时,会触发Python的垃圾回收机制,对可回收对象进行回收,而那些不可回收的对象会被移到中年代去。依此类推,老年代对象是存活时间最久的对象,甚至有可能存活在整个系统的生命周期内。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python新手实现2048小游戏
Mar 31 Python
pymongo给mongodb创建索引的简单实现方法
May 06 Python
python利用不到一百行代码实现一个小siri
Mar 02 Python
Python socket套接字实现C/S模式远程命令执行功能案例
Jul 06 Python
Python3解释器知识点总结
Feb 19 Python
python自定义函数实现最大值的输出方法
Jul 09 Python
对Django项目中的ORM映射与模糊查询的使用详解
Jul 18 Python
python虚拟环境完美部署教程
Aug 06 Python
python自动化工具之pywinauto实例详解
Aug 26 Python
五分钟带你搞懂python 迭代器与生成器
Aug 30 Python
Django数据模型中on_delete使用详解
Nov 30 Python
Python调用SMTP服务自动发送Email的实现步骤
Feb 07 Python
Python通过cv2读取多个USB摄像头
Aug 28 #Python
python3.5 cv2 获取视频特定帧生成jpg图片
Aug 28 #Python
Django--权限Permissions的例子
Aug 28 #Python
Python中函数的返回值示例浅析
Aug 28 #Python
django认证系统实现自定义权限管理的方法
Aug 28 #Python
Python中注释(多行注释和单行注释)的用法实例
Aug 28 #Python
对Django的restful用法详解(自带的增删改查)
Aug 28 #Python
You might like
短波收音机简介
2021/03/01 无线电
对text数据类型不支持代码页转换 从: 1252 到: 936
2011/04/23 PHP
thinkphp实现多语言功能(语言包)
2014/03/04 PHP
PHP简单实现文本计数器的方法
2016/04/28 PHP
jquery 将disabled的元素置为enabled的三种方法
2009/07/25 Javascript
javascript写的一个链表实现代码
2009/10/25 Javascript
让IE6支持min-width和max-width的方法
2010/06/25 Javascript
Js中setTimeout()和setInterval() 何时被调用执行的用法
2013/04/12 Javascript
JS 使用for循环遍历子节点查找元素
2014/09/06 Javascript
jQuery网页定位导航特效实现方法
2016/12/19 Javascript
node.js+jQuery实现用户登录注册AJAX交互
2017/04/28 jQuery
js如何获取网页所有图片
2017/05/12 Javascript
Vue中定义全局变量与常量的各种方式详解
2017/08/23 Javascript
JavaScript中使用参数个数实现重载功能
2017/09/01 Javascript
对layui初始化列表的CheckBox属性详解
2019/09/13 Javascript
python 参数列表中的self 显式不等于冗余
2008/12/01 Python
尝试用最短的Python代码来实现服务器和代理服务器
2016/06/23 Python
详解python进行mp3格式判断
2016/12/23 Python
Python正则捕获操作示例
2017/08/19 Python
用python实现百度翻译的示例代码
2018/03/09 Python
python实现多线程网页下载器
2018/04/15 Python
Python+OpenCV目标跟踪实现基本的运动检测
2018/07/10 Python
python实现大文本文件分割
2019/07/22 Python
Python爬虫HTPP请求方法有哪些
2020/06/03 Python
Python3+RIDE+RobotFramework自动化测试框架搭建过程详解
2020/09/23 Python
Python列表的深复制和浅复制示例详解
2021/02/12 Python
英国最大的化装舞会服装网站:Fancydress.com
2017/08/15 全球购物
匈牙利超级网上商店和优惠:Alza.hu
2019/12/17 全球购物
工程师岗位职责
2013/11/08 职场文书
三好学生自我鉴定
2013/12/17 职场文书
爱心倡议书范文
2014/05/12 职场文书
奥林匹克运动会口号
2014/06/19 职场文书
家庭贫困证明书(3篇)
2014/09/15 职场文书
2014年十一国庆节爱国演讲稿
2014/09/23 职场文书
欢迎家长标语
2014/10/08 职场文书
学校百日安全活动总结
2015/05/07 职场文书