Python 垃圾回收机制 (引用计数+标记清除+分代回收)

Python垃圾回收机制(引用计数+标记清除+分代回收)

Python中的垃圾回收是以引用计数为主,分代收集为辅。引用计数的缺陷是循环引用的问题。
在Python中,如果一个对象的引用数为0,Python虚拟机就会回收这个对象的内存。

  • 有三种情况会触发垃圾回收:

    1.调用gc.collect(),
    2.当gc模块的计数器达到阀值的时候。
    3.程序退出的时候

  • gc模块的自动垃圾回收机制

    必须要import gc模块,并且is_enable()=True才会启动自动垃圾回收。
    这个机制的主要作用就是发现并处理不可达的垃圾对象。
    垃圾回收=垃圾检查+垃圾回收
    在Python中,采用分代收集的方法。把对象分为三代,一开始,对象在创建的时候,放在一代中,如果在一次一代的垃圾检查中,改对象存活下来,就会被放到二代中,同理在一次二代的垃圾检查中,该对象存活下来,就会被放到三代中。

    gc模块里面会有一个长度为3的列表的计数器,可以通过gc.get_count()获取。
    例如(488,3,0),其中488是指距离上一次一代垃圾检查,Python分配内存的数目减去释放内存的数目,

    注意是内存分配,而不是引用计数的增加

    应用

  • 项目中避免循环引用

  • 引入gc模块,启动gc模块的自动清理循环引用的对象机制

  • 由于分代收集,所以把需要长期使用的变量集中管理,并尽快移到二代以后,减少GC检查时的消耗

  • gc模块唯一处理不了的是循环引用的类都有__del__方法,所以项目中要避免定义__del__方法,如果一定要使用该方法,同时导致了循环引用,需要代码显式调用gc.garbage里面的对象的__del__来打破僵局

引用计数

优点:简单实时,一旦没有引用,内存就直接释放了。不用像其他机制等到特定时机。实时性还带来一个好处:处理回收内存的时间分摊到了平时。

缺点:维护引用计数消耗资源,会造成循环引用导致无法回收,造成内存泄露。

标记-清除

1、首先标记对象(垃圾检测),然后清除垃圾(垃圾回收)。
在这里插入图片描述

2、首先初始所有对象标记为白色,并确定根节点对象(这些对象是不会被删除),标记它们为黑色(表示对象有效)。

3、将有效对象引用的对象标记为灰色(表示对象可达,但它们所引用的对象还没检查),检查完灰色对象引用的对象后,将灰色标记为黑色。

4、重复直到不存在灰色节点为止。最后白色结点都是需要清除的对象。

分代回收

1、分代技术是一种典型的以空间换时间的技术,这也正是java里的关键技术。这种思想简单点说就是:对象存在时间越长,越可能不是垃圾,应该越少去收集。

2、这样的思想,可以减少标记-清除机制所带来的额外操作。分代就是将回收对象分成数个代,每个代就是一个链表(集合),代进行标记-清除的时间与代内对象

3、存活时间成正比例关系。

4、从上面代码可以看出python里一共有三代,每个代的threshold值表示该代最多容纳对象的个数。默认情况下,当0代超过700,或1,2代超过10,垃圾回收机制将触发。

5、0代触发将清理所有三代,1代触发会清理1,2代,2代触发后只会清理自己。

Rp_
发布了103 篇原创文章 · 获赞 28 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/weixin_41738030/article/details/104256363
今日推荐