垃圾回收

为什么要垃圾回收

程序运行中,有些不再使用的对象持续占有内存,称之为内存泄漏memory leak.

内存泄漏导致计算机崩溃.

例如,服务程序(长期运行)中发生内存泄漏会导致内存被占满,会导致计算机崩溃.

好在python作为一种易用的语言,我们不用亲自进行内存管理(反面的是c语言,程序员必须非常注意内存管理).

python的垃圾回收机制

引用计数

对每一个对象进行计数,ob_refcnt记录了一个对象被引用的次数.

当引用计数归零时,回收对象(被动触发)

sys.getrefcount()可以获取一个对象的ob_refcnt 引用增加的情况:

  • 对象被创建,例如 a=23

  • 对象被引用,例如 b=a

  • 对象被作为参数,传入到一个函数中,例如get_refcnt(a)

  • 对象作为一个元素,存储在容器中,例如list1=[a,a]\

引用减少的情况:

  • 对象的别名被显式销毁,例如del a

  • 对象的别名被赋予新的对象,例如a=24

  • 一个对象离开它的作用域,例如 f 函数执行完毕时,func函数中的局部变量(全局变量不会)

  • 对象所在的容器被销毁,或从容器中删除对象

优缺点

  • 优点:被动进行,消耗资源少

  • 缺点:无法解决循环引用问题

标记清除

一个程序的所有引用关系构成一个有向图,标记清除法就是从顶层对象Roots递归所有引用关系,不可达的对象将会被删除.(主动进行)

分代回收

每当对象在某次的的垃圾回收中存活下来时,则将该对象移动至下一代.

代数越多,说明这个对象越可能重要,于是减少垃圾回收频率.

内存模型

Python内存管理机制——内存模型