22_Python垃圾回收机制

一、对象池

1、小整数对象池
1). 整数在程序中的使用非常广泛,Python为了优化速度,使用了小整数对象池,避免为整数频繁申请和销毁内存空间。
2). Python对小整数的定义是[-5,257)
这些整数对象是提前建立好的,不会被垃圾回收。在一个Python的程序中,所有位于这个范围内的整数使用的都是同一个对象.
2、大整数对象池
每个大整数,均创建一个新的对象
3、intern机制
string interning (字符串驻留):它通过维护一个字符串常量池(string intern pool),从而试图只保存唯一的字符串对象,达到既高效又节省内存的处理字符串的目的。
在创建一个新的字符串对象后,Python 先比较常量池中是否有相同的对象(interned),
有的话则将指针指向已有对象,并减少新对象的指针,新对象由于没有引用计数,就会被垃圾回
收机制回收掉,释放出内存。
字符串(含有空格),不可修改,没开启intern机制,不共用对象,引用计数为0,销毁

二、垃圾回收机制

1、内存溢出与内存泄露?
内存溢出 out of memory是指程序在申请内存时,没有足够的内存空间供其使用,
出现out of memory;比方说,定义了20个字节大小的内存空间,却写入了21个字
节的数据。通俗的说,就是内存不够,没办法支持当前程序。当发生内存溢出时,程
序将无法进行,强制终止。
内存泄露 memory leak,是指程序在申请内存后,无法释放已申请的内存空间,一次内存
泄露危害可以忽略,但内存泄露堆积后果很严重,无论多少内存,迟早会被占光。如果发生内
存泄露,那么可用内存会逐渐减少,从而降低性能。

memory leak会最终会导致out of memory
2、为什么需要Garbage collection?
为了防止内存泄露. 对编程语言来说,GC 就是一个无名英雄,默默地做着贡献。
打个比方,天鹅在水面优雅地游动时,实际上脚蹼却在水下拼命地划水。GC 也是如此。
在由编程语言构造的美丽的源代码这片水下,GC在拼命地将垃圾回收再利用。
3、python采用的是引用计数机制为主,标记-清除和分代收集两种机制为辅的策略

三、垃圾回收:计数机制

1、GC 原本是一种“释放怎么都无法被引用的对象的机制”。那么人们自然而然地就会
想到,可以让所有对象事先记录下“有多少程序引用自己”。让各对象知道自己的“人气指
数”,从而让没有人气的对象自己消失,这就是引用计数法(Reference Counting).
在这里插入图片描述
清除这些无用的垃圾对象,把它们送回到可用列表
2、python里每一个东⻄都是对象,它们的核心就是结构体: PyObject
3、对象的引用计数器+1
1). 对象被创建,例如a=23
2). 对象被引用,例如b=a
3). 对象被作为参数,传入到一个函数中,例如func(a)
4). 对象作为一个元素,存储在容器中,例如list1=[a,a]
4、对象的引用计数器-1
1). 对象的别名被显式销毁,例如del a
2). 对象的别名被赋予新的对象,例如a=24
3). 一个对象离开它的作用域,例如f函数执行完毕时,func函数中的局部变量的引用计数器就会减1(全局变量不会)
4). 对象所在的容器被销毁,或从容器中删除对象
5、引用计数法的优点
1).高效
2).运行期没有停顿 可以类比一下Ruby的垃圾回收机制,也就是 实时性:一旦没有引用,内存就直接释放了。不用像其他机制等到特定时机。实时性还带来一个好处:处理回收内存的时间分摊到了平时。
3).对象有确定的生命周期
4).易于实现
6、缺点
1).维护引用计数消耗资源,维护引用计数的次数和引用赋值成正比,而不像mark and sweep等基本与回收的内存数量有关。
2).无法解决循环引用的问题。A和B相互引用而再没有外部引用A与B中的任何一个,它们的引用计数都为1,但显然应该被回收。
四、垃圾回收:标记-清除
1、如它的字面意思一样,GC 标记 - 清除算法由标记阶段和清除阶段构成。标记阶段是
把所有活动对象都做上标记的阶段。清除阶段是把那些没有标记的对象,也就是非活动对象回收的阶段。通过这两个阶段,就可以令不能利用的内存空间重新得到利用。

『标记清除(Mark—Sweep)』算法是一种基于追踪回收(tracing GC)技术实现的垃圾回收算法。它分为两个阶段:第一阶段是标记阶段,GC会把所有的『活动对象』打上标记,第二阶段是把那些没有标记的对象『非活动对象』进行回收。那么GC又是如何判断哪些是活动对象哪些是非活动对象的呢?
对象之间通过引用(指针)连在一起,构成一个有向图,对象构成这个有向图的节点,而引用关系构成这个有向图的边。从根对象(root object)出发,沿着有向边遍历对象,可达的(reachable)对象标记为活动对象,不可达的对象就是要被清除的非活动对象。根对象就是全局变量、调用栈、寄存器。

五、垃圾回收:分代收集
1、分代垃圾回收(Generational GC)在对象中导入了“年龄”的概念,通过优先回收容
易成为垃圾的对象,提高垃圾回收的效率。
2、gc的逻辑

分配内存
-> 发现超过阈值了
-> 触发垃圾回收
-> 将所有可收集对象链表放到一起
-> 遍历, 计算有效引用计数
-> 分成 有效引用计数=0 和 有效引用计数 > 0 两个集合
-> 大于0的, 放入到更老一代
-> =0的, 执行回收
-> 回收遍历容器内的各个元素, 减掉对应元素引用计数(破掉循环引用)
-> 执行-1的逻辑, 若发现对象引用计数=0, 触发内存回收
-> python底层内存管理机制回收内存

3、分代回收是一种以空间换时间的操作方式,Python将内存根据对象的存活时间划分为不同的集合,每个集合称为一个代,Python将内存分为了3“代”,分别为年轻代(第0代)、中年代(第1代)、老年代(第2代),他们对应的是3个链表,它们的垃圾收集频率与对象的存活时间的增大而减小。新创建的对象都会分配在年轻代,年轻代链表的总数达到上限时,Python垃圾收集机制就会被触发,把那些可以被回收的对象回收掉,而那些不会回收的对象就会被移到中年代去,依此类推,老年代中的对象是存活时间最久的对象,甚至是存活于整个系统的生命周期内。同时,分代回收是建立在标记清除技术基础之上。分代回收同样作为Python的辅助垃圾收集技术处理那些容器对象.
在这里插入图片描述
六、gc模块
gc模块提供操作垃圾回收的接口,包括禁用gc,调整回收频率,配置debug选项,
同时提供对无法释放内存对象的访问权。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值