【Python基础知识库】Python内存管理与垃圾回收机制

Python垃圾回收机制详解

Python GC主要使用引用计数(reference counting)来跟踪和回收垃圾。在引用计数的基础上,通过标记清除机制(mark and sweep)解决容器对象可能产生的循环引用问题,通过分代回收(generation collection)策略,以以空间换时间的方法来提高垃圾回收的效率。

  • 引用计数

引用计数法的原理是每个对象维护一个ob_ref,用来记录当前对象被引用的次数,也就是来追踪到底有多少引用指向了这个对象,当发生(对象被创建、对象被引用、对象被作为参数传到函数中、对象作为一个元素,存储在容器中)四种情况的时候,该对象的引用计数+1;当发生(该对象的别名被显示销毁时、该对象的引别名被赋予新的对象、一个对象离开它的作用域、该元素从容器中删除时或容器被销毁时),该对象的引用计数器-1。

简而言之,PyObject是每个对象必有的内容,其中ob_refcnt就是做为引用计数。当有一个对象有心的引用时,它的ob_refcnt就会增加,当引用它的对象被删除,它的ob_refcnt就会减少。当引用计数为0时,该对象生命就结束了。

优点:
① 高效
② 运行期没有停顿
③ 对象有确定的生命周期
④ 易于实现

缺点:
① 维护引用计数消耗资源,维护引用计数的次数和应用赋值成正比,而不像mark and sweep等基本与回收的内存数量有关。
② 无法解决循环引用的问题。

  • 标记清除机制(mark and sweep)

基本思路是先按需分配,等到没有空闲内存的时候从寄存器和程序栈上的引用出发,遍历以对象为节点、以引用为边构成的图,把所有可以访问到的对象打上标记,然后清扫一遍内存空间,把所有没有标记的对象释放。为了保证效率,Python只会在垃圾达到一定阈值时,垃圾回收才会启动。主要处理对象是一些容器对象,如list、dict、tuple、set、instance等,因为对于字符串、数值对象是不可能造成循环引用问题。

缺点:
①清除非活动对象前必须顺序扫描整个堆内存,哪怕只剩下小部分活动对象也要扫描所有对象。

  • 分带回收策略

分代回收的整体思想是:将系统中所有的内存块根据其存活时间划分为不同的集合,每个集合就成为一个“代”,python将内存等为3“代”,分别是年轻代(第0代)、中年代(第1代)、老年代(第2代),它们对应的是三个链表,它们的垃圾回收集频率随着“代”的存活时间的增大而减小,新创建的对象都会分配在年轻代,年轻代链表总数达到上限时,python垃圾回收机制就回被触发,把那些可以被回收的对象回收,而那些不被回收的对象就会移到中年代去,以此类推,老年代中的对象是存活时间最久的对象,甚至是存活于整个系统的生命周期,存活时间通常利用经过几次垃圾回收来度量。同时,分代回收是建立在标记清除技术基础之上。

Python默认定义三代对象集合,索引越大,对象存活时间越长。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值