Python小白垃圾回收机制入门


Posted in Python onJune 09, 2020

引用计数

Python默认的垃圾收集机制是“引用计数”,每个对象维护了一个ob_ref字段。它的优点是机制简单,当新的引用指向该对象时,引用计数加1,当一个对象的引用被销毁时减1,一旦对象的引用计数为0,该对象立即被回收,所占用的内存将被释放。它的缺点是需要额外的空间维护引用计数,不过最主要的问题是它不能解决“循环引用”。

什么是循环引用?A和B相互引用而再没有外部引用A与B中的任何一个,它们的引用计数虽然都为1,但显然应该被回收,例子:

a = { } # a 的引用为 1
b = { } # b 的引用为 1
a['b'] = b # b 的引用增 1,b的引用为2
b['a'] = a # a 的引用增 1,a的引用为 2
del a # a 的引用减 1,a的引用为 1
del b # b 的引用减 1, b的引用为 1

在这个例子中,del语句减少了 a 和 b 的引用计数并删除了用于引用的变量名,可是由于两个对象各包含一个对方对象的引用,虽然最后两个对象都无法通过名字访问了,但引用计数并没有减少到零。因此这个对象不会被销毁,它会一直驻留在内存中,这就造成了内存泄漏。为了解决循环引用问题,Python引入了标记-清除和分代回收两种GC机制。

标记清除

标记——清除(Mark——Sweep)是一种基于追踪(Tracing)回收技术实现的垃圾回收算法,对象之间通过引用(指针)连在一起,构成一个有向图,对象构成这个有向图的节点,而引用关系构成这个有向图的边。从根对象(root object)出发,沿着有向边遍历对象,可达的对象标记为有用的对象,不可达的对象就是要被清除的对象。所谓根对象就是一些全局引用对象和函数栈中的引用,这些引用所引用的对象是不可被删除的。

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

分代回收

分代回收是一种以空间换时间的操作方式,Python将内存根据对象的存活时间划分为不同的集合,每个集合称为一个代,Python将内存分为了3“代”,分别为年轻代(第0代)、中年代(第1代)、老年代(第2代),他们对应的是3个链表,它们的垃圾收集频率与对象的存活时间的增大而减小。新创建的对象都会分配在年轻代,年轻代链表的总数达到上限时,Python垃圾收集机制就会被触发,把那些可以被回收的对象回收掉,而那些不会回收的对象就会被移到中年代去,依此类推,老年代中的对象是存活时间最久的对象,甚至是存活于整个系统的生命周期内。同时,分代回收是建立在标记清除技术基础之上。

分代回收同样作为Python的辅助垃圾收集技术处理那些容器对象。

实例扩展:

引用计数实例

import sys
class A():
 def __init__(self):
  '''初始化对象'''
  print('object born id:%s' %str(hex(id(self))))
 def f1():
 '''循环引用'''
 while True:
  c1=A()
  c2=A()
  c1.t=c2
  c2.t=c1
  del c1
  del c2

到此这篇关于Python小白垃圾回收机制入门的文章就介绍到这了,更多相关Python垃圾回收机制详解内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
python错误:AttributeError: 'module' object has no attribute 'setdefaultencoding'问题的解决方法
Aug 22 Python
pymongo实现控制mongodb中数字字段做加法的方法
Mar 26 Python
Python正则表达式教程之三:贪婪/非贪婪特性
Mar 02 Python
Python编写登陆接口的方法
Jul 10 Python
Python有序查找算法之二分法实例分析
Dec 11 Python
python 利用栈和队列模拟递归的过程
May 29 Python
在python里协程使用同步锁Lock的实例
Feb 19 Python
Python基础之循环语句用法示例【for、while循环】
Mar 23 Python
Python QQBot库的QQ聊天机器人
Jun 19 Python
python实现测试工具(二)——简单的ui测试工具
Oct 19 Python
详解Python GUI编程之PyQt5入门到实战
Dec 10 Python
python源文件的字符编码知识点详解
Mar 04 Python
Python中如何添加自定义模块
Jun 09 #Python
sklearn线性逻辑回归和非线性逻辑回归的实现
Jun 09 #Python
Python如何避免文件同名产生覆盖
Jun 09 #Python
对Keras中predict()方法和predict_classes()方法的区别说明
Jun 09 #Python
Python嵌入C/C++进行开发详解
Jun 09 #Python
Keras load_model 导入错误的解决方式
Jun 09 #Python
如何用python处理excel表格
Jun 09 #Python
You might like
使用PHP备份MySQL和网站发送到邮箱实例代码
2013/11/28 PHP
编写PHP脚本使WordPress的主题支持Widget侧边栏
2015/12/14 PHP
浅析PHP7 的垃圾回收机制
2019/09/06 PHP
Prototype PeriodicalExecuter对象 学习
2009/07/19 Javascript
jquery 操作单选框,复选框,下拉列表实现代码
2009/10/27 Javascript
jQueryPad 实用的jQuery测试工具(支持IE,chrome,FF)
2010/05/22 Javascript
JavaScript验证电子邮箱的函数
2014/08/22 Javascript
node.js中的http.request方法使用说明
2014/12/14 Javascript
TypeScript 中接口详解
2015/06/19 Javascript
JavaScript数组对象赋值用法实例
2015/08/04 Javascript
超精准的javascript验证身份证号的具体实现方法
2015/11/18 Javascript
Javascript之面向对象--封装
2016/12/02 Javascript
轻松理解Javascript变量的相关问题
2017/01/20 Javascript
JS去掉字符串末尾的标点符号及删除最后一个字符的方法
2017/10/24 Javascript
AngularJS日期格式化常见操作实例分析
2018/05/17 Javascript
Angular Material Icon使用详解
2018/11/07 Javascript
微信小程序本地存储实现每日签到、连续签到功能
2019/10/09 Javascript
p5.js临摹旋转爱心
2019/10/23 Javascript
vue 导航守卫和axios拦截器有哪些区别
2020/12/19 Vue.js
[02:43]DOTA2英雄基础教程 德鲁伊
2014/01/13 DOTA
[01:13:08]2018DOTA2亚洲邀请赛4.6 淘汰赛 mineski vs LGD 第二场
2018/04/10 DOTA
[01:16:12]完美世界DOTA2联赛PWL S2 FTD vs Inki 第一场 11.21
2020/11/23 DOTA
Python+OpenCV人脸检测原理及示例详解
2020/10/19 Python
Python进阶之递归函数的用法及其示例
2018/01/31 Python
python爬虫之urllib库常用方法用法总结大全
2018/11/14 Python
Python 从一个文件中调用另一个文件的类方法
2019/01/10 Python
PyCharm 配置远程python解释器和在本地修改服务器代码
2019/07/23 Python
python PIL/cv2/base64相互转换实例
2020/01/09 Python
美国高端婴童品牌:Hanna Andersson
2016/10/30 全球购物
Toppik顶丰增发纤维官网:解决头发稀疏
2017/12/30 全球购物
暑期社会实践学生的自我评价
2014/01/09 职场文书
好军嫂事迹材料
2014/01/15 职场文书
幼儿园数学教学反思
2014/02/02 职场文书
捐款倡议书格式范文
2014/05/14 职场文书
捐助倡议书
2015/01/19 职场文书
《我们的民族小学》教学反思
2016/02/19 职场文书