Python垃圾回收机制(GC)和内存池
Python垃圾回收机制(GC)
Python中 gc
模块负责垃圾回收。
GC机制分为:
- 引用计数 (主要)
- 分代回收 (辅助)
- 标记-清除 (辅助)
触发垃圾回收时刻:
- 程序退出时
- gc模块计数器到达阈值
- 手动调用
gc.collect()
引用计数
优点:
- 简单
- 实时性,一旦对象引用计数为0,立即回收,释放内存
缺点:
- 无法处理循环引用,导致内存泄漏
- 维护引用计数消耗资源
- 有时候比较慢,释放一个大对象,里面有很多元素,GC要一个一个释放。(这个可说可不说)
每个对象都有一个引用计数。如果一个对象被其他对象引用、作为参数被使用等等,引用计数加1;对象引用被删除、作为参数时函数执行完以后引用计数减1。引用计数减为0时,GC回收该对象,释放内存。
分代收集
分代收集分为三代,解决了循环引用问题。
- 零代,创建的新对象都放入零代。新对象相对不稳定,GC清理最频繁。
- 一代,被分配计数达到一定阈值,触发GC分代收集,释放一些对象,剩余的为一代。
- 二代,再次触发分代收集,释放一些对象,剩余的为二代。
长期使用的,访问活跃的对象会从零代到一代,再到二代。二代里保存的都是长期使用的,活跃的。
GC清理的频繁度为:零代 > 一代 > 二代
标记-清除
分为两个阶段,第一阶段把所有还在使用中的对象打上标记,第二阶段把没有标记的对象回收释放。
Python内存管理
创建对象时,Python会随用随申请,用完就释放。创建大量对象会频繁向系统申请内存,影响效率,所以Python引入了内存池机制,用于管理小块内存的申请和释放。
申请内存时,小于256字节的都用内存池(Pymalloc),大于256字节的向系统申请内存(malloc)。
如果对象创建是从内存池申请的内存,回收时也释放回内存池。