Python内存的一些有趣的问题
2019-09-29 本文已影响0人
10xjzheng
1.特权种族:共用内存的对象
- 对于整数对象,如果其值处于[-5,256]的闭区间内,则值相同的对象是同一个对象。
- 字符串使用Intern机制实现内存地址共用,长度不超过20,且仅包括下划线、数字、字母的字符串才会被intern;涉及字符串拼接时,编译期优化结果会与运行期计算结果不同。
>>> b=256
>>> a=256
>>> id(a)==id(b)
True
>>> a=257
>>> b=257
>>> id(a)==id(b)
False
>>> s="python_cat"
>>> t="python_cat"
>>> id(s)==id(t)
True
2.常见数据类型的内存大小
import sys
sys.getsizeof("") # 49
sys.getsizeof([]) # 64
sys.getsizeof(()) # 48
sys.getsizeof(set()) # 224
sys.getsizeof(dict()) # 240
# 作为参照:
sys.getsizeof(1) # 28
sys.getsizeof(True) # 28
排一下序:基础数字<空元组 < 空字符串 < 空列表 < 空集合 < 空字典。
因为这些空对象都是容器,我们可以抽象地理解:它们的一部分内存用于创建容器的骨架、记录容器的信息(如引用计数、使用量信息等等)、还有一部分内存则是预分配的。
空对象并不为空,一部分原因是 Python 解释器为它们预分配了一些初始空间。在不超出初始内存的情况下,每次新增元素,就使用已有内存,因而避免了再去申请新的内存。
可变对象在扩充时的秘密:
- 超额分配机制:申请新内存时并不是按需分配的,而是多分配一些,因此当再添加少量元素时,不需要马上去申请新内存
- 非均匀分配机制:三类对象申请新内存的频率是不同的,而同一类对象每次超额分配的内存并不是均匀的,而是逐渐扩大的
消减元素并不会释放内存。