您当前的位置:首页 > 计算机 > 编程开发 > Python

Python 源码剖析 - PyListObject 对象缓冲池

时间:12-14来源:作者:点击数:
城东书院 www.cdsy.xyz

还记得吗,刚才我们按下了一个有趣的话题。没错,就是那个缓冲池,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* 列表占用的内存,重新拥抱新的对象。放眼四周,曾经所拥有过的那些对象,有的已经容颜苍老,有的已经烟消云散,是否有一种无私人非事事休,欲语泪先流的感慨呢?

城东书院 www.cdsy.xyz
方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门
本栏推荐