python垃圾回收的三种方法
①引用计数
当一个对象的引用被创建或复制时,对象引用计数加一,当对象的引用被销毁时 引用计 数减一
当对象的引用计数为0时 就意味着对象已经没有使用了,就可以将其内存释放掉
优点:
实时性,任何内存,一旦没有指向它的引用,就会被立即回收,而其他的垃圾收集技 术必须在某种特殊条件下才能进行无效内存的回收。
缺点:
对象之间相互引用,每个对象的引用都不会为0,所以这些对象所占用的内存始终都不会被释放掉。
效率低
②标记-清除
1、标记-清除: 只关注那些可能会产生循环引用的对象
2、整型、字符串这些不可变对象是不可能产生循环引用的,因为它们内部不可能持有其它对象的引用。
3、Python中的循环引用总是发生在可变对象之间,也就是能够在内部持有其它对象的对象,比如list、dict、class等等。
4、所以该方法带来的开销只依赖于可变对象的的数量.
5、大白话: 把活跃对象做标记,把哪些没有标记的都清除回收
优点:
清除算法的优点,那当然要数算法简单,实现容易了。
另外,如果算法实现简单,那么它与其他算法的组合也就相应地简单。
缺点:
标记和清除的过程效率不高
使用过程中会逐渐产生被细化的分块,不久后就会导致无数的 小分块散布在堆的各处。我们称这种状况为碎片化(fragmentation)。
原理:
把所有可以访问到的对象打上标记,然后清扫一遍内存空间,把所有没标记的对象释放
③分代回收
将系统中的所有内存块根据其存活时间划分为不同的集合,每一个集合就成为一个“代”,垃圾收集的频率随着“代”的存活时间的增大而减小。
也就是说,活得越长的对象,就越不可能是垃圾,就应该减少对它的垃圾收集频率。
那么如何来衡量这个存活时间:通常是利用几次垃圾收集动作来衡量,如果一个对象经过的垃圾收集次数越多,可以得出:该对象存活时间就越长。
优点:
吞吐量得到改善
通过使用分代垃圾回收,可以改善 GC 所花费的时间(吞吐量)。正如 Ungar 所说的那 样:“据实验表明,分代垃圾回收花费的时间是 GC 复制算法的 1/4。”可见分代垃圾 回收 的导入非常明显地改善了吞吐量。
另一方面,因为老年代 GC 很费时间,所以我们没法缩短 mutator 的最大暂停时间。关 于使用分代垃圾回收来缩减 mutator 最大暂停时间的方法
缺点:
在部分程序中会起到反作用
对对象会活得很久的程序执行分代垃圾回收,就会产生以下两个问题。
新生代GC所花费的时间增多
老年代GC频繁运行
考虑到这两点,恐怕我们没法利用到分代垃圾回收的优点,或者就算利用到了,效果 也 甚微。