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

转载自https://blog.csdn.net/joeyon1985/article/details/41961827
python里也同java一样采用了垃圾收集机制,不过不一样的是,python采用的是引用计数机制为主,标记-清除和分代收集两种机制为辅的策略。

1. 引用计数

PyObject

  1. python里每一个东西都是对象,它们的核心就是一个结构体:PyObject
  2. PyObject是每个对象必有的内容,其中ob_refcnt就是做为引用计数。当一个对象有新的引用时,它的ob_refcnt就会增加,当引用它的对象被删除,它的ob_refcnt就会减少

引用计数优缺点

  1. 优点
    简单实时,一旦没有引用,内存就直接释放了。不用像其他机制等到特定时机。实时性还带来一个好处:处理回收内存的时间分摊到了平时。
  2. 缺点
    维护引用计数消耗资源,会造成循环引用导致无法回收,造成内存泄露

循环应用

list1 = []
list2 = []
list1.append(list2)
list2.append(list1)
  • list1与list2相互引用,如果不存在其他对象对它们的引用,list1与list2的引用计数也仍然为1,所占用的内存永远无法被回收,这将是致命的。

2. 标记-清除

  1. 标记-清除机制,顾名思义,首先标记对象(垃圾检测),然后清除垃圾(垃圾回收)。如图:
    标记清除
  2. 首先初始所有对象标记为白色,并确定根节点对象(这些对象是不会被删除),标记它们为黑色(表示对象有效)。
  3. 将有效对象引用的对象标记为灰色(表示对象可达,但它们所引用的对象还没检查),检查完灰色对象引用的对象后,将灰色标记为黑色。
  4. 重复直到不存在灰色节点为止。最后白色结点都是需要清除的对象。

3. 分代回收

  1. 分代技术是一种典型的以空间换时间的技术,这也正是java里的关键技术。这种思想简单点说就是:对象存在时间越长,越可能不是垃圾,应该越少去收集。
  2. 这样的思想,可以减少标记-清除机制所带来的额外操作。分代就是将回收对象分成数个代,每个代就是一个链表(集合),代进行标记-清除的时间与代内对象
  3. 存活时间成正比例关系。
  4. 从上面代码可以看出python里一共有三代,每个代的threshold值表示该代最多容纳对象的个数。默认情况下,当0代超过700,或1,2代超过10,垃圾回收机制将触发。
  5. 0代触发将清理所有三代,1代触发会清理1,2代,2代触发后只会清理自己。

猜你喜欢

转载自blog.csdn.net/wxfghy/article/details/80901488
今日推荐