刚开始学python时候,发现一个很迷惑的现象,一直到看了源码后才知道了:
>>> a=6 >>> b=6 >>> a is b True
想用同样的参数初始化两个对象,结果却是,这两个对象其实是同样的对象????逗我呢?
>>> a=666 >>> b=666 >>> a is b False
这又是怎么回事?为什么现在又是False了???
这些不同,主要来自于python中对待小整数和大整数的初始化方式不同,而且他们都是在对象池中的,只不过所在的对象池不同。。。
那么,什么是小整数,什么又是大整数?在python中默认-5~256为小整数,其余的为大整数。。。
>>> a=256 >>> b=256 >>> a is b True >>> a=257 >>> b=257 >>> a is b False
那么问题又来了,为什么要区分小整数和大整数?
因为如果不停的调用malloc和free,会严重的影响python的性能,为了减少malloc和free的次数,python会预先初始化所有小整数的对象,也就是说,在我们用小整数对象的时候,没有创建,没有初始化,而是得到了一个本来就在内存中的小整数对象的引用
如果小整数太多的话,会占用太多的内存,也会影响性能的,所以Guido大叔就默认了-5~256为小整数。
那么,大整数是怎么初始化的?
为了减少创建大整数对象时候减少malloc和free的次数,当用到大整数时候,python会一次malloc几十个大整数对象的链表,称为一个block,一个block占用1k空间,大概可以存放40个整数对象,然后用一个block_list指针指向所有分配的整数对象的链表,当这个block用完的时候,再malloc从下一个block。
那么,问题又来了,比如,如果第二个block中的内存还没用完,第一个block中已经有对象不用了怎么办?岂不是就浪费了
在python中,会有一个free_list的指针指向所有可用的对象内存,当某个对象不用的时候,就添加到free_list链表中。
发现了什么,竟然只有malloc,没有free,没有内存交换系统。
python中应该还有另外一个机制防止内存泄露。。。这个现在就还不明白怎么做到的了
参考资料:python源码剖析