美文网首页
Python 垃圾回收学习

Python 垃圾回收学习

作者: vckah | 来源:发表于2018-07-16 17:28 被阅读0次

    垃圾回收机制一般有两个阶段:垃圾检测和垃圾回收。
    Python GC 主要使用引用计数来跟踪和垃圾回收。在引用计数的基础上,通过“标记-清除”解决容器对象可能产生的循环引用问题,通过“分代回收”以空间换时间的方法来提高垃圾回收效率。
    Python 的垃圾回收经历了三个阶段:

    • 引用计数
      每个对象维护一个引用计数,用来记录该对象当前被引用的次数,每当新的引用指向该对象时,它的引用计数会 +1,当对象的引用失效时,引用计数 -1。一旦引用计数为 0,那么对象立即被回收,对象占用的内存空间会被释放。但是它无法解决对象的“循环引用”。我估计 C++ 程序员对这块应该特别理解。
      Python 通过 sys 模块来查看对象的引用计数
    >>> import sys
    >>> a = [1, 2]
    >>> sys.getrefcount(a)
    2
    # 为什么会是 2 呢?因为传入函数时也使用的是引用
    # 但是这里还有一个很令我迷惑的问题
    # 当引用计数一个 数字的时候,这个值很大
    >>> sys.getrefcount(2)
    931          --> 你机器上可能会不同
    # 难道是因为 2 在 Python 中被缓存了??
    

    有几种方式可以增加引用计数:
    对象被创建 , 别名被创建
    传递给函数, 成为容器对象的一个元素
    减少引用计数方式:
    对象/别名被销毁, 离开函数作用域

    • 标记清除
      标记清除(Mark—Sweep)算法是一种基于追踪回收(tracing GC)技术实现的垃圾回收算法。等到没有空闲内存的时候,从寄存器和栈上的引用出发,遍历以对象为节点、以引用为边构成的图,把所有可以访问到的对象上打标记,然后清扫内存,没有标记的对象释放。
    • 分代回收
      分代回收是一种以空间换时间的操作方式,Python将内存根据对象的存活时间划分为不同的集合,每个集合称为一个代,Python将内存分为了3“代”,分别为年轻代(第0代)、中年代(第1代)、老年代(第2代),他们对应的是3个链表,它们的垃圾收集频率与对象的存活时间的增大而减小。新创建的对象都会分配在年轻代,年轻代链表的总数达到上限时,Python垃圾收集机制就会被触发,把那些可以被回收的对象回收掉,而那些不会回收的对象就会被移到中年代去,依此类推,老年代中的对象是存活时间最久的对象,甚至是存活于整个系统的生命周期内。同时,分代回收是建立在标记清除技术基础之上。

    来自于网上:
    Python 实现了一个内存池机制,将不同的内存放到操作系统而不是返回给操作系统。Python 中所有小于 256 字节的对象都使用 pymalloc 实现的分配器,大对象使用系统的 malloc。

    相关文章

      网友评论

          本文标题:Python 垃圾回收学习

          本文链接:https://www.haomeiwen.com/subject/ztibpftx.html