Python变量的内存机制
Python 对象池、字符串itern机制、垃圾回收
1. 小整数和字符串对象池
1.1 小整数
1.2 大整数
不再上述范围内的大整数 都需要重新创建(超过256的id就变了)
1.3 字符串
默认开启itern机制
在shell中示例,并非全部的字符串都会采用intern机制。仅仅包括下划线、数字、字母的字符串才会被 intern,当然不能超过20个字符。因为如果超过20个字符的话,解释器认为这个字符串不常用,不用放入字符串池中
is 相等代表两个对象的 id 相同(从底层来看的话,可以看作引用同一块内存区域)
python字符串的intern机制:
字符串类型作为Python中最常用的数据类型之一,Python解释器为了提高字符串使用的效率和使用性能,做了很多优化,例如:Python解释器中使用了 intern(字符串驻留)的技术来提高字符串效率,什么是intern机制?即值同样的字符串对象仅仅会保存一份,放在一个字符串储蓄池中,是共用的,当然,肯定不能改变,这也决定了字符串必须是不可变对象。
简单原理:
实现 Intern 机制的方式非常简单,就是通过维护一个字符串储蓄池,这个池子是一个字典结构,如果字符串已经存在于池子中就不再去创建新的字符串,直接返回之前创建好的字符串对象,如果之前还没有加入到该池子中,则先构造一个字符串对象,并把这个对象加入到池子中去,方便下一次获取。
但是,解释器内部对intern 机制的使用策略是有考究的,有些场景会自动使用intern ,有些地方需要通过手动方式才能启动
1.4 pycharm中的现象
但是在Pycharm中 整数超过256 和 字符串即使带有空格也都认为地址一样,20个字符以内
str1 = 'asfd*a10 asd'
str2 = 'asfd*a10 asd'
print(id(str1),id(str2))
print(str1 == str2)
a = 257
b = 257
print(id(a),id(b))
结果如下所示:
2. 垃圾回收 GC 垃圾回收Garbage collection
引用计数为主。隔代回收为辅
一个字节占8位 int 2**32长度
缺点维护统计 消耗资源
解决不了循环引用
2.1 Python对象分配
Ruby与python的区别
ruby会一直申请使用内存空间 ,直到可用的被用完,才开始清理内存
python当一个内存没有被使用时 立刻被清除
隔代回收
-
循环引用
-
检测循环引用
0代链表 即没有被引用的。如图所示 除了ABC,DEF还有三个其他的对象存在于零代链表,蓝色的箭头指示有一些对象
正在被零代链表之外的其他对象引用。所以他们有更高的引用计数。
当链表到达一定程度时就会检测 循环引用 如果有的话就会减一
2.2 GC 模块
- 操作函数
- 触发回收机制,避免程序崩溃
- GC 手动回收
gc.collect() (gc.garbage()保存着已经清除的垃圾对象) - 程序自己关闭
- 开启自动回收机制