Cpython list
typedef struct { PyObject_VAR_HEAD PyObject **ob_item; Py_ssize_t allocated; } PyListObject;PyListObject对应list对象
PyObject对应python对象
ob_item为list元素的所有指针,数据类型为数组(非链表!)
当list大小发生变化时,ob_list的需要重新分配空间大小,采用预分配方式,算法如下:
new_allocated = (newsize >> 3) + (newsize < 9 ? 3 : 6);new_allocated为比总要求大小(newsize)多出来的部分,即预分配的部分
举例来说,要求list总大小为4
预分配 (3 >> 3) + 3 = 3 ,那么分配空间大小为 4 + 3(预分配) = 7
那么什么时候会触发预分配呢?
已分配的空间不够用的时候。
当
已分配大小allocated的一半 < 总要求大小newsize < 已分配大小allocated不会触发预分配。
同样的,当
总要求大小newsize < 已分配大小allocated的一半会进行空间回收。
回收同样根据上面的算法,算出需要分配的值然后回收多余的。
举例来说, 已分配大小allocated为8,但总要求大小newsize为3的时候,
因为 3 < (8 // 2),重新计算需要分配的空间,3 + 3 = 6
那么回收8 - 6 = 2 两个空间大小
另外list对象有一个list池(free_list)默认大小为80
当需要销毁一个list对象的时候(比如list的引用计数为0)
这个list对象中的元素的所有指针(ob_item)都将被销毁,指针指向的的对象则等待GC处理 free)list中还有空间的话,这个list对象不会被销毁,而是放到free_list这个list池中,可被重复利用,不必再次生成list对象(对应CPython中的PyListObject结构体) free_list没有空间,那么该list对象被立即销毁