python内存管理机制
1. 前言
控制python内存,对python内存进行回收。
1.1 关于python的存储问题
- 由于python中万物皆对象,所以python的存储问题是对象的存储问题,并且对于每个对象,python会分配一块内存空间去存储它
- 对于整数和短小的字符等,python会执行缓存机制,即将这些对象进行缓存,不会为相同的对象分配多个内存空间
- 容器对象,如列表、元组、字典等,存储的其他对象,仅仅是其他对象的引用,即地址,并不是这些对象本身
2. 垃圾回收GC
java和python中存在垃圾回收机制(Garbage collection)(java存在于JVM,python存在与python解释器中),会自动回收没有用的内存;C#和C++中没有该机制,需要手动回收,内存泄露是最常见的问题。
2.1 GC功能
3.python中的GC
采用引用计数机制(记录对象被引用的次数)为主,标记-清除和分代收集两种机制为辅的策略。
3.1 引用计数机制
3.1.1 祖先object的底层
python底层用c语言写的。
所有对象的祖先为Object,结构体为PyObject。
如下:
PyObject结构体中有计数参数(refcnt)和类型参数(ob_type),并定义了计数的增加和减少。
3.1.2 引用计数的优点和缺点
最大的缺点为循环引用(两个对象对象引用),循环引用清楚不了。
3.1.2 引用计数变化情况
-
引用计数+1
代码演示:
-
引用计数-1
注意闭包会维持变量引用。
删除的时候可能会引发其它机制,如标记-清除和分代回收。
3.1.3 引用计数的查看
利用sys模块中getrefcount方法
3.1.4 循环引用的问题
引用计数解决不了循环引用问题。需要gc中的分代回收管理进行回收,如下,关闭gc(主要关闭里面的分代回收),然后c1和c2循环引用,此时进程占用会不断增大。
3.1.5 触发垃圾回收机制的情况
- gc.collet()
主动回收 - 当gc模块的计数器达到阀值时
三个阀值 - 程序退出的时候
3.1.6 GC中的方法
- gc.garbage
垃圾回收的对象会放在该列表中 - gc.get_count()
返回长度为3的列表,分别表示第一代对象,第二对象和对三代对象值。 - gc.get_threshold()
返回长度为3的列表,分别表示第一代对象,第二对象和对三代对象的阀值。 - gc.collect([第几代])
- gc.disable