垃圾回收机制

垃圾回收机制

    垃圾回收机制(Garbage Collection:GC)基本是所有高级语言的标准配置之一了。在一定程度上,能优化编程语言的数据处理效率和提高编程软件开发软件的安全性能。
    在 PYTHON 中的垃圾回收机制主要是以引用计数为主要手段,以标记清除和分代回收机制作为辅助操作手段,完成对内存中无效数据的自动管理操作的!

引用计数

    引用计数[Reference Counting:RC]是 PYTHON 中的垃圾回收机制的核心操作算法。该算法最早是 George E.Collins 在 1960 年首次提出的,并在大部分高级语言中沿用至今,是很多高级语言的垃圾回收核心算法之一

(1) 什么是引用计数
    引用计数算法的核心思想是:当一个对象被创建或者拷贝时,引用计数就会+1,当这个对象的多个引用变量,被销毁一个时该对象的引用计数就会-1,如果一个对象的引用计数为 0 则表示该对象已经不被引用,就可以让垃圾回收机制进行清除并释放该对象占有的内存空间了。
    引用计数算法的优点是:操作简单,实时性能优秀,能在最短的时间获得并运算对象引用数.
    引用计数算法的缺点是:为了维护每个对象的引用计数操作算法,PYTHON 必须提供和对象对等的内存消耗来维护引用计数,这样就在无形中增加了内存负担;同时引用计数对于循环 应用/对象之间的互相引用,是无法进行引用计数操作的,所以就会造成常驻内存的情况。

(2) PYTHON 中的引用计数
    PYTHON是一个面向对象的弱类型语言,所有的对象都是直接或者间接继承自object类型, object 类型的核心其实就是一个结构体对象。

typedef struct_object {
    int ob.refcnt;
    struct_typeobject *ob_type;
} PyObject;

    在这个结构体中,ob_refcnt就是对象的引用计数,当对象被创建或者拷贝时该计数就会增加1,当对象的引用变量被删除时,该计数就会减少1,当引用计数为0时,对象数据就会被回收释放。在python中,可以通过下面的方式获取一个对象的引用计数:

import sys
sys.getrefcount(对象名)

代码示例:


引用计数代码示例

标记清除

    PYTHON中的标记清除机制主要是针对可能产生循环引用的对象进行的检测机制。在python中的基本不可变类型,如:PyIntObject,PyStringObject等对象的内部不会内聚其他对象的引用,所以不会产生循环引用,一般情况下循环引用总是发生在其他可变对象的内部属性中,如list,dict,class等等,使得该方法消耗的资源和程序中可变对象的数量息息相关!

    标记清除算法核心思想:首先找到PYTHON中的一批根节点对象,如object对象,通过根节点对象可以找到他们指向的子节点对象,如果搜索过程中这个指向是从上往下的指向,那么表示这个对象是可达的,否则该对象是不可达的,可达部分的对象在程序中需要保留下来,不可达部分的对象在程序中是不需要保留的。
对于如下代码:

class A:
    pass
class B:
    pass
a = A()
b = B()
a.bb = b
b.aa = a
代码运行结果

如果代码中执行了

del a
del b

    我们会发现,对象A()和对象B()依然有指向引用他们,如果是之前的引用计数方式明显区分不了这样的对象是否应该删除,但是标记清楚的方式就可以标记出来对象A()和对象B()是不可达对象,不需要保留,直接删除即可!


标记清除(红色部分的引用被删除)

分代回收

    PYTHON中的分代回收机制是一种通过空间换取时间效率的做法,PYTHON内部处理机制定义了三个不同的链表数据结构[第零代(年轻代),第1代(中年代),第2代(老年代)]。PYTHON为了提高执行效率,将垃圾回收机制进行了阈值限定,0代链表中的垃圾回收机制执行最为密集,其次是1代,最后是2代。
    PYTHON定义的这三个链表,主要是针对我们在程序中创建的对象,首先会添加到0代链表:



    随后0代链表数量达到一定的阈值之后,出发GC算法机制,对0代对象进行符合规则的引用计数运算,避免出现对象的延迟或过早释放。



    最终,触发GC机制将已经没有引用指向的对象进行回收,并将有引用指向的对象移动到第1代对象链表中;第1代对象链表的对象,就是比第0代对象链表中的对象可能存活更久的对象,GC阈值更大,检测频率更慢,以提高程序执行效率。

    以此类推,直到一部分对象存活在第2代对象链表中,对象周期较长的可能会跟程序的生命周期一样。

备注:
弱代假说:程序中年轻的对象往往死的更快,年老的对象往往存活更久

垃圾回收处理

对PYTHON中的垃圾回收机制有了一定的了解之后,我们针对垃圾回收机制的代码进行测试。
PYTHON中的gc模块提供了垃圾回收处理的各项功能机制,必须引入进去才能使用:

模块引入
import gc
设置 gc 的 debug 日志,一般为 gc.DEBUG_LEAK
gc.set_debug(flags)
显式进行垃圾回收处理,可以输入参数,参数表示回收的对象代数,0 表示只检查第 0 代对象,1 表示检查第 0、1 代对象,2 表示检查 0、1、2 代对象,如果不传递参数,执行 FULL COLLECT,也就是默认传递 2
gc.collect([generation])
设置执行垃圾回收机制的频率
gc.set_threshold(threshold0 [,threshold2 [,threshold3]])
获取程序对象引用的计数器
gc.get_count()
获取程序自动执行 GC 的引用计数阈值
gc.get_threshold()

以上是 PYTHON 中垃圾回收机制的基本操作,在程序开发过程中需要注意:
⚫ 项目代码中尽量避免循环引用
⚫ 引入 gc 模块,启用 gc 模块自动清理循环引用对象的机制
⚫ 将需要长期使用的对象集中管理,减少 GC 资源消耗
⚫ gc模块处理不了重写del方法导致的循环引用,如果一定要添加该方法,需要显式调用 gc模块的garbage中对象的del方法进行处理。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,377评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,390评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,967评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,344评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,441评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,492评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,497评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,274评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,732评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,008评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,184评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,837评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,520评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,156评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,407评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,056评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,074评论 2 352

推荐阅读更多精彩内容

  • 虽然是自己转载的但是是真的好的一篇图文并茂的对垃圾回收机制的讲解!!! 先来个概述,第二部分的画述才是厉害的。 G...
    东皇Amrzs阅读 118,638评论 13 176
  • 来自: Android梦想特工队作者: Aaron主页: http://www.wxtlife.com/原...
    技术特工队阅读 4,365评论 0 28
  • JVM内存区域 JVM将其管理的内存分为若干数据区域,这些数据区域分布情况如下图所示: 程序计数器:一块较小内存区...
    luoxn28阅读 694评论 0 0
  • 现在的高级语言如java,c#等,都采用了垃圾收集机制,而不再是c,c++里用户自己管理维护内存的方式。但是这种方...
    LittlePy阅读 736评论 0 1
  • 一、垃圾回收机制的意义Java语言中一个显著的特点就是引入了垃圾回收机制,使c++程序员最头疼的内存管理的问题迎刃...
    任任任任师艳阅读 634评论 0 0