一、引用计数

Python 垃圾回收以引用计数为主,分代回收为辅。引用计数法的原理是每个对象维护一个ob_refcnt,用来记录对象被引用的次数,也就是用来追踪有多少个引用指向了对象,当发生以下四种情况的时候,对象的引用计数+1:

对象被创建,比如:a = 14

对象被引用,比如: b = a

对象被作为参数,传给函数,比如:func(a)

对象作为容器中的一个元素,比如:List = {a, ”a” , ”b”, 2}

与上述情况相对应,当发生以下四种情况时,对象的引用计数-1:

对象的别名被显式销毁,比如:del a

对象的别名被赋予新的对象,比如:a = 26

对象离开它的作用域,比如 func() 执行完毕时,函数里面的所有局部变量的引用计数都会减 1

将元素从容器中删除,或者容器被销毁

当对象的引用计数为 0 时,它将被 Python 虚拟机回收。

在 Python 中一切皆对象,它们的核心是 Py_Object 结构体,所有 Python 对象的头部都包含该结构:

// object.h

#define PyObject_HEAD

_PyObject_HEAD_EXTRA

Py_ssize_t ob_refcnt;

struct _typeobject *ob_type;

typedef struct _object {

PyObject_HEAD

} PyObject;

比如 int 类型的定义如下:

// intobj.h

typedef struct {

PyObject_HEAD

long ob_ival;

} PyIntObject;

简而言之,PyObject 是每个对象必有的内容,其中 ob_refcnt 是对象的引用计数。对象有新的引用时,它的 ob_refcnt 会增加;当对象的引用被删除时,ob_refcnt 会减少。当引用计数为 0 时,对象的生命周期就结束了。

// object.h

#define Py_INCREF(op) (

_Py_INC_REFTOTAL _Py_REF_DEBUG_COMMA

((PyObject*)(op))->ob_refcnt++)

#define Py_DECREF(op)

do {

if (_Py_DEC_REFTOTAL _Py_REF_DEBUG_COMMA

--((PyObject*)(op))->ob_refcnt != 0)

_Py_CHECK_REFCNT(op)

else

_Py_Dealloc((PyObject *)(op));

} while (0)

引用计数有很明显的优点:

高效

运行期没有停顿,即实时性:对象一旦没有引用,将直接被释放。实时性还带来一个好处是:处理回收内存的时间分摊到了平时

对象有确定的生命周期

易于实现

原始的引用计数法也有明显的缺点:

维护引用计数消耗资源,维护引用计数的次数和引用赋值成正比

无法解决循环引用的问题

比如:

list1 = []

list2 = []

list1.append(list2)

list2.append(list1)

为了解决这两个致命弱点,Python 又引入了以下两种 GC 机制。

二、标记-清除

『标记-清除(Mark-Sweep)』算法是一种基于追踪回收(tracing GC)技术实现的垃圾回收算法。它分为两个阶段:第一阶段是标记阶段,GC 会给所有『活动对象』打上标记;第二阶段是回收没有标记的『非活动对象』。那么 GC 如何判断哪些是活动对象、哪些是非活动对象呢?

对象之间通过引用(指针)连在一起,构成一个有向图。对象是有向图的顶点,引用关系是有向图的弧。从根对象(root object)出发,遍历有向图,将可达的(reachable)对象标记为活动对象,不可达的对象就是要被清除的非活动对象。根对象是全局变量、调用栈、寄存器。

在上图中,把小黑圈视为全局变量,也就是把它作为 root object,从小黑圈出发,对象 1 可直达,那么它将被标记,对象 2、3 可间接到达,也会被标记,而 4 和 5 不可达,因此 1、2、3 是活动对象,4 和 5 是非活动对象,会被 GC 回收。

标记清除算法作为 Python 的辅助垃圾回收技术,主要用于处理容器对象,比如 list、dict、tuple、instance 等,因为字符串、数值等原子类型的对象不可能造成循环引用问题。Python 使用双向链表将容器对象组织起来。不过这种简单粗暴的标记清除算法也有明显的缺点:清除非活动对象前,必须顺序扫描整个堆内存,哪怕只剩下小部分非活动对象,也要扫描所有对象。

三,分代回收

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

以上就是python中的GC机制的详细内容,更多关于python GC的资料请关注云海天教程其它相关文章!

原文链接:http://timd.cn/python/gc/?utm_source=tuicool&utm_medium=referral

python gc教程_python中的垃圾回收(GC)机制相关推荐

  1. python有向图_Python 中的垃圾回收机制

    一.概述 python采用的是引用计数机制为主,标记-清除和分代收集(隔代回收)两种机制为辅的策略. 现在的高级语言如java,c#等,都采用了垃圾收集机制,而不再是c,c++里用户自己管理维护内存的 ...

  2. 关于python的垃圾回收机制_Python中的垃圾回收机制

    GC作为现代编程语言的自动内存管理机制,专注于两件事:1. 找到内存中无用的垃圾资源 2. 清除这些垃圾并把内存让出来给其他对象使用.GC彻底把程序员从资源管理的重担中解放出来,让他们有更多的时间放在 ...

  3. 简述python垃圾回收机制_python中的垃圾回收机制简述

    2020年12月5日21:47:35 王凯玉 python中的垃圾回收机制 引用计数 # 引用计数 引用计数是编程语言中的一中内存管理技术,可以将资源的被引用次数保存起来. 当引用计数为0时,资源将被 ...

  4. python 垃圾回收哪时候执行_Python 中的垃圾回收机制是如何工作的?

    CPython 中垃圾回收的主要思路 1.维护引用计数器 .对于每一个对象,都有一个对于该对象的引用次数的计数器.如果这个计数器的值减为了 0 ,这就代表这个对象在程序中已经没用了,那么该对象所占用的 ...

  5. python asyncio教程_python中使用asyncio实现异步IO实例分析

    1.说明 Python实现异步IO非常简单,asyncio是Python 3.4版本引入的标准库,直接内置了对异步IO的支持. asyncio的编程模型就是一个消息循环.我们从asyncio模块中直接 ...

  6. python numpy教程_Python中的Numpy入门教程

    这篇文章主要介绍了 Python 中的 Numpy 入门教程,着重讲解了矩阵中的数组操作 , 需要的 朋友可以参考下 1 . Numpy 是什么 很简单, Numpy 是 Python 的一个科学计算 ...

  7. python zipfile教程_Python中zipfile压缩文件模块的基本使用教程

    zipfile Python 中 zipfile 模块提供了对 zip 压缩文件的一系列操作. f=zipfile.ZipFile("test.zip",mode="&q ...

  8. python正则表达式教程_Python中正则表达式的巧妙使用一文包你必掌握正则,

    Python中正则表达式的巧妙使用一文包你必掌握正则, 前言 正则表达式就是从字符串中发现规律,并通过"抽象"的符号表达出来.打个比方,对于2,5,10,17,26,37这样的数字 ...

  9. python zipfile教程_Python中的zipfile模块使用详解

    zip文件格式是通用的文档压缩标准,在ziplib模块中,使用ZipFile类来操作zip文件,下面具体介绍一下: class zipfile.ZipFile(file[, mode[, compre ...

最新文章

  1. Android 的NDK的Makefile编写
  2. 老牌医药收割AI红利:先投个15亿美元抢中国人才
  3. 详细配置架设自己的Serv-U FTP服务器图文教程
  4. JavaScript数组方法大全(推荐)
  5. 磁盘阵列掉电 oracle数据库,掉电导致磁盘坏,非归档下的redo全部丢失,数据库打开的恢复失败...
  6. 如何在linux下启动和关闭oracle服务
  7. 英国拟对英伟达收购Arm展开深入调查
  8. 车站广播系统采用计算机,公共广播系统
  9. 文本居于图片左侧html,CSS实现图片与文本的居中对齐的常见方式
  10. python3 readlines的参数_Python3 File readlines() 方法
  11. 计算机系统字体安装程序,电脑安装字体的三种方式
  12. 惠普服务器做虚拟化,节省成本立竿见影 惠普虚拟化技术详解
  13. ISIS路由过载概述
  14. 江在川上曰:vue-Router学习笔记
  15. 【NOI OJ】4977 怪盗基德的滑翔翼
  16. requests---timeout请求超时
  17. 客户端与平台存在有状态连接的系统蓝绿发布方案设计
  18. HDU 6447 YJJ's Salesman
  19. BackTrack 4 R1 – Public Release
  20. linux操作系统-----用户与组管理(3)

热门文章

  1. 惠普1139一体打印机如何联网打印_涨姿势:手把手教你如何连接网络打印机
  2. html css怎么换字体颜色,css怎么设置字体颜色?
  3. 山河无恙,人间正沧桑
  4. pow函数有四样写法,你知道吗
  5. 读阮一峰ES6—Set数据结构
  6. Delphi之access violation at address错误
  7. ABAQUS学习记录:刚体(Rigid body)约束
  8. 【事务代码】MF60-拉料清单
  9. 数据可视化之Echarts-lines3D动态轨迹渲染
  10. 20X23 FCPX插件10组创意图像拼接排版LOGO标志展示片头 Abstract Photo Openers