还记得吗,刚才我们按下了一个有趣的话题。没错,就是那个缓冲池,free_list。现在,是揭开它的神秘面纱的时候呢。我们想知道的问题是:free_list中所缓冲的PyListObject对象是从哪里获得的,是在何时创建的。答案就在一个 PyListObject 被销毁的过程中:
[listobject.c]
static void list_dealloc(PyListObject *op)
{
int i;
PyObject_GC_UnTrack(op);
Py_TRASHCAN_SAFE_BEGIN(op)
if (op->ob_item != NULL) {
/* Do it backwards, for Christian Tismer.
There's a simple test case where somehow this reduces
thrashing when a *very* large list is created and
immediately deleted. */
i = op->ob_size;
while (--i >= 0) {
Py_XDECREF(op->ob_item[i]);
}
PyMem_FREE(op->ob_item);
}
if (num_free_lists < MAXFREELISTS && PyList_CheckExact(op))
free_lists[num_free_lists++] = op;
else
op->ob_type->tp_free((PyObject *)op);
Py_TRASHCAN_SAFE_END(op)
}
在销毁一个PyListObject的时候,当然要做的一件事是为list中的每一个元素改变其引用计数。然后,我们就来到了最有趣的部分。Python会检查我们开始提到的那个缓冲池,free_lists,查看其中缓存的PyListObject的数量是否已经满了,如果没有,就将该待删除的PyListObject放到缓冲池中,以备后用。
现在一切真相大白了,那个在Python启动是空荡荡的缓冲池原来都是被本应该死去的PyListObject对象给填充了 ,在以后创建新的PyListObject的时候,Python会首先唤醒这些已经“死去”的PyListObject。感谢党,感谢政府,又给它们一个重新做人的机会。
但是,需要指出,这里缓冲的仅仅是PyListObject对象,而没有这个对象曾经拥有的PyObject*列表,因为这些PyObject指针的引用计数已经减少了,这些指针所指的对象都要各奔前程,或生存,或毁灭,不再被PyListObject所给与的那个引用计数所束缚。PyListObject如果继续维护一个指向这些对象的指针的列表,就可能产生悬空指针的问题。所以,PyObject*列表所占用的空间必须归还给系统。
看一下我们刚刚创建的PyListObject的最后归宿:

在下一次创建 PyListObject 时,这个PyListObject将重新被唤醒,重新分配 PyObject* 列表占用的内存,重新拥抱新的对象。放眼四周,曾经所拥有过的那些对象,有的已经容颜苍老,有的已经烟消云散,是否有一种无私人非事事休,欲语泪先流的感慨呢?

