Python中的GC机制:¶
- 以引用计数为主
- 分代回收为辅
python对象的核心是一个结构体:PyObject
1 2 3 4 5 6 7 8 9 10 11 12 | |
ob_refcnt 就是为了做引用计数,当一个对象的引用为0时,会被清除。
Python在合适的时机会对处在链表中的有循环引用的对象引用减1,这样,原本有引用的对象不会被清除,而原本循环引用的对象,其引用计数被置零并回收。
零代链中的无引用对象,将剩余有引用对象挪到一代链,对一代链同理。这三代链子被清理的频率:零代 >> 一代 >> 二代
1 2 3 4 5 6 7 | |
Python和Ruby的标记-清除机制对比:
Ruby:一次性创建大量可用对象,用完后标记清除。
Python:初始化时才创建对象,一旦引用为0立即清除。
一点注意¶
如果类的__del__方法被重写(未调用父类的del方法),则执行垃圾回收时无法回收该对象。
引用计数相关¶
导致引用计数 +1 的情况¶
- 对象被创建
- 对象被引用
- 对象被传入函数中
- 对象作为一个元素存放在容器中
导致引用计数 -1 的情况:¶
- 对象被 del 显式销毁
- 对象被赋予新的对象
- 一个对象离开其作用域(如已经执行完毕的函数中的形参)
- 对象所在的容器被销毁
查看对象的引用计数:¶
1 2 3 4 | |
整数对象池¶
小整数对象池¶
为了避免整数的频繁申请和销毁内存空间,Python使用了小整数对象池。
[-5, 257)内的整数都在小整数对象池中,他们都已经被提前建立好了,常驻内存,不被回收。
大整数对象池¶
每一个大整数的定义都会创建一个新的对象。
字符串共享机制(intern)¶
1 2 3 4 5 | |
a1-a5拥有共同的id(实际指向了同一块内存),但如果字符串中有特殊字符(如空格),则不会触发共享机制共享。