python中创建的对象时,首先会去申请内存地址,然后对对象进行初始化,所有对象都会维护到一个叫做refchain的双向循环链表中,每个数据都保存如下信息
- 链表中数据前后数据的指针
- 数据的类型
- 数据值
- 数据的引用计数
- 数据的长度
引用计数机制
引用计数增加:
- 对象被创建
- 对象被别的变量引用 (另外起了名字)
- 对象被作为元素,放在容器中 (比如被当做元素放在列表中
引用计数减少:
- 对象的别名被显示的销毁
- 对象的一个别名被赋值给其他对象 (例如:a=10 被改成 a=100)
- 对象从容器中被移除,或者容器被销毁 (例如: 对象从列表中被移除,或者列表被销毁)
- 一个引用离开了它的作用域 (调用函数的时候传进去的参数,在函数运行结束后,该参数的引用即被销毁)
查看引用计数
import sys
sys.getrefconut(obj)
数据池和缓存
1、小整数池
python自动将 -5至256的整数进行缓存到一个小整数池中,当你将这些整数赋值给变量时,并不会重新创建对象,而是使用已经创建好的缓存对象,
当删除这些数据的引用时,也不会进行回收
2、intern机制
intern机制 ,也称为字符串驻留池,是针对于字符串内存管理的一致优化处理的机制
优点:在创建新的字符串对象时,先在缓存池里面找是否已经存在的值相同的对象(标识符,即只包含数字、字母、下划线的字符串,ascii码中的字符),如果有,则直接拿过来用,避免频繁的创建和销毁内存,提升效率
3、缓存机制
- float、int、list等一些内置的数据类型,会缓存80个对象。
- 元组 会根据元组数据的长度,分别缓存元组长度为0-20的对象。
- 其他的类型缓存2个对象。
垃圾回收机制
python的垃圾回收机制:引用计数机制为主,标记-清除和分代收集两种为辅的策略
1、引用计数
- 每个对象创建之后都有一个引用计数,当引用计数为0的时候,那么此时的垃圾回收机制会自动把它销毁,回收内存空间
- 缺点:当2个对象出现循环引用,那么这两个变量始终不会被销毁,会导致内存泄漏
2、标记清除
3、分代回收
第0代链表 当对象数达到700时,开始垃圾回收,未被回收的放入下一代链表
第1代链表 当第0代链表回收十次之后,第1代链表进行一次回收,未被回收的放入下一代
第2代链表 当第1代链表回收十次之后,第2代链表进行一次回收,未被回收的放入下一代
gc模块
gc.get_threshold: 获取分代回收的频率
返回值为(700,10,10)这也是gc的默认值,在第0代对象数量达到700个之前,不把未被回收的对象放入第一代;
而在第一代对象数量达到10个之前也不把未被回收的对象移到第二代
gc.set_threshold:设置分代回收的频率