Python 采用引用计数的方式来管理分配的内存。Python 的每个对象都有一个引用计数,这个引用计数表明了有多少对象在指向它。当这个引用计数为 0 时,释放该对象的内存。为了解决循环引用的问题,Python提供了“标记-清除”法,用于释放循环引用的对象。
为了加速Python的执行效率,Python 同时使用了一个内存池机制,用于管理对小块内存的申请和释放。 Python 的垃圾收集并不会把不用的内存返回给操作系统,而是放到了内存池。对于 int, float, list 对象, Python 还提供了独立的私有内存池。
Python 通过引用计数来确定当前变量是否需要释放。每个对象都有一个计数器,当一个对象的引用计数为0时,就会由 gc 模块来执行内存释放操作。假如这个对象在缓冲区内,那么它地址空间不会被释放,而是等待下一次被使用,而非缓冲区的该释放就释放。
对于普通对象 gc 采取分代回收算法,对象根据存活的时间分为三“代”,所有新建的对象都是0代,当0代对象经过一次自动垃圾回收,没有被释放的对象会被归入1代,同理1代归入2代。
对于因循环引用而无法释放的对象,Python 采用“标记-清除”法。
Python 下造成内存泄漏的原因大概有这几方面:
- 对象一直被全局变量所引用, 全局变量生命周期长.
- 垃圾回收机被禁用或者设置成debug状态, 垃圾回收的内存不会被释放.
- 循环引用过多, gc 无法及时释放