Python中引用计数del语句以及小整数缓存池

del语句

我们知道一个对象的引用计数为0时,python会删除该对象,释放内存。这种说法不是很对。严格来说,当一个对象引用计数为0时,会调用tp_dealloc的函数,这个通常是将对象所占用的内存还给python解释器,一般是还给python中的对象内存池,等待新生。而不是将空间还给操作系统。
这种借尸还魂的好事,当然只有python的内置类型才能享受到这个待遇,自建类型就是另外一回事了。

>>> for i in range(1000,1005):
...     print(id(i))
...
4531590160
4529696528
4531590160
4529696528
4531590160

id 代表了对象在python内存中的位置。

可以看到,这个变量 i 在两个尸体里钻来钻去,反复诈尸。

del 语句,新手通常把它当作删除对象,这当然是不正确的,严格来说,应该是解除变量与对象之间的关系,删除变量,然后将对象的引用数字减一。应该意识到变量与对象不是一回事,在python中,变量与对象直接通常使用一个字典存储器来的映射关系,多个对象可以映射到同一个对象中。字典中,key不能重复,value就未必了。

这也就是为什么有人嘲笑,python把什么东西都想用字典装起来的原因。

小整数缓存池

python利用小整数池存储-5到257之间的小整数,这个应该很多人都知道了,不过我的文章主要还是写给新手小白的(因为我自己就是一个新手 手动颜文字),不妨再说一遍。
python中的小整数池机制实际上是一个长度为 5+1+257 长度的数组,数组里面存储的是指向指针 PyIntObject 类型的指针,里面的数字当然是 -5 到 257了。

这些整数在python运行之初进行初始化,当python准备创建一个整数对象的时候,他首先会检查整数是否在 -5到257之间,如果是的话,就直接在整数池里拉一个引用来。因为装载小整数指针的结构是c语言中的数组,所以速度很快。

其实不光是整数类型实现了内存池的机制,string类型也是如此,他同样会把所有的ascii单字符的字符串,缓存到一个字符串对象池中, 如‘a’,‘b’等。这里只想说明将常用的小对象缓存起来是python的一个常见机制,其核心思想是空间换时间。

>>> l = [1,2,3]
>>> l2 = [1,2,3]
>>> for i in l:
...     print(id(i))
...
4527790128
4527790160
4527790192
>>> for i in l2:
...     print(id(i))
...
4527790128
4527790160
4527790192

来源,参考知乎大佬-闲谈后

你可能感兴趣的:(Python中引用计数del语句以及小整数缓存池)