How does Python detect & free circular memory references before making use of the gc module?
它不。 gc仅用于检测和释放循环引用。非循环引用通过引用计数来处理。
现在,要了解gc如何确定任何给定对象引用的对象集,请查看Modules / gcmodule.c中的gc_get_references函数。相关位为:
// Where `obj` is the object who's references we want to find
traverseproc traverse;
if (! PyObject_IS_GC(obj))
continue;
traverse = Py_TYPE(obj)->tp_traverse;
if (! traverse)
continue;
if (traverse(obj, (visitproc)referentsvisit, result)) {
Py_DECREF(result);
return NULL;
}
这里的主要功能是tp_traverse。每个C级类型定义一个tp_traverse函数(或者在没有任何引用的对象的情况下,如str,将其设置为NULL)。 tp_traverse的一个示例是list_traverse,list的遍历函数:
static int
list_traverse(PyListObject *o, visitproc visit, void *arg)
{
Py_ssize_t i;
for (i = Py_SIZE(o); --i >= 0; )
Py_VISIT(o->ob_item[i]);
return 0;
}
I see is a statement that circular references are detected, except when the objects involved have a __del__() method.
你是正确的 – Python的循环检测器可以检测和收集周期,除非它们包含带有__del__方法的对象,因为没有办法让解释器安全地删除这些对象(为了获得直观的原因,想象你有两个对象与__del__方法相互引用,它们应该按什么顺序释放?)。
当一个循环中包含带有__del__方法的对象时,垃圾收集器会将它们粘贴在一个单独的列表中(通过gc.garbage访问),以便程序员可以手动“处理”它们。