1、对象池
1、小整数对象池
- 整数在程序中的使用非常广泛,Python为了优化速度,使用了小整数对象池,避免为整数频繁申请和销毁内存空间。
- Python对小整数的定义是[-5,257)这些整数对象是建立在提前建立好的,不会被垃圾回收。在一个python的程序中,所有位于这个范围内的整数使用的都是同一个对象。
2、大整数对象池
每一个大整数,均创建一个新的对象。
3、intern机制
string interning(字符串驻留):通过维护一个字符串常量池(string intern pool),从而试图只保存唯一的字符串对象,达到即高效又节省内存地处理字符串的目的。
在创建一个新的字符串对象后,python先比较常量池中是否有相同的对象,有的话则将指针指向已有的对象,并减少新对象的指针,新对象由于没有引用计数,就会被垃圾回收机制收掉,释放出内存。
字符串(含有空格),不可修改,没有开启intern机制,引用计数为0,销毁。
2.1、垃圾回收机制–引用计数
1、内存溢出与内存泄漏
内存溢出是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory;比方说,定义了20字节大小的内存空间,却写入了21个字节的数据。内存不够用,没办法支持当前程序。当发生内存溢出时,程序将无法进行,强制终止。
内存泄漏是指程序在申请内存后,无法释放已申请的内存空间。如果发生内存泄漏,那么可用内存就会逐渐减少,从而降低性能。
2、Garbage collection可以防止内存泄漏
3、python采用的是引用计数法(将引用自己的次数记录下来)为主,标记-清除和分代收集两种机制为辅的策略
4、可以导致引用计数+1的情况
- 对象被创建,例如a = 23
- 对象被引用,例 b = a
- 对象被作为参数,传入到一个函数中,例如fun(a)
- 对象作为一个元素,存储在容器中。例如:str1 =[a,a]
5、导致引用计数-1的情况
- 对象的别名被显示销毁,例:del a
- 对象的别名被赋予新的对象。例如:a = 24
- 一个对象离开它的作用域,例如函数执行完毕时,func函数中的局部变量(全局变量不会)
- 对象所在的容器被销毁,或从容器中删除对象
6、引用计数发的优缺点
- 优点:简单;实时性:一旦没有引用内存就直接释放了。
- 缺点:维护引用计数消耗资源;循环引用
2.2垃圾回收机制–标记清除
1、标记清除:将那些没有标记的对象,也就是非活动对象回收的阶段。通过这两个阶段,就可以使得不能利用的内存空间重新得到利用。
2.3垃圾回收机制–分代收集
1、分代垃圾回收在对象中通过优先回收容易成为垃圾的对象,提高垃圾回收的效率。
2、新生代对象和老年代对象:
1). 分代垃圾回收中把对象分类成几代,针对不同的代使用不同的GC算法,我们把刚生成的对象称为新生代对象,达到一定的年龄的对象则称为老年代对象。
2).新生代GC将存活了一定次数的新生代对象当作老年代对象来处理。我们把类似于这样的新生对象上升为老年代对象的情况称为晋升。
3). 老年代对象很难称为垃圾,所以我们对老年代对象减少执行GC的频率,从而提高效率。
3、gc模块
gc模块提供操作垃圾回收的接口,包括禁用gc,调整回收频率,设置debug选项,同时提供对无法解释内存对象的访问权。