Python的可选垃圾收集器gc
忽略contain any object with a __del__
method:
版本3.4中更改:在PEP 442之后,使用
__del__()
方法的对象不再在gc.garbage
中结束。
Cython扩展类型可以有__dealloc__
方法,但no __del__
method:
注意:扩展类型没有
__del__()
方法。
出于收集周期的目的,是否存在由垃圾收集器处理的__dealloc__
,好像存在__del__
方法一样?或者__dealloc__
对垃圾收集器是不可见的吗?
答案 0 :(得分:1)
如果查看生成的C代码,可以看到Cython在tp_dealloc
插槽中生成析构函数,而不是tp_del
插槽
cdef class B:
def __dealloc__(self):
pass
产生
static PyTypeObject __pyx_type_5cy_gc_B = {
PyVarObject_HEAD_INIT(0, 0)
"cy_gc.B", /*tp_name*/
sizeof(struct __pyx_obj_5cy_gc_B), /*tp_basicsize*/
0, /*tp_itemsize*/
__pyx_tp_dealloc_5cy_gc_B, /*tp_dealloc*/
/* lines omitted */
0, /*tp_del*/
0, /*tp_version_tag*/
#if PY_VERSION_HEX >= 0x030400a1
0, /*tp_finalize*/
#endif
};
您也可以轻松验证其他示例的情况(例如,自动生成__dealloc__
的类)。
从Python 3.4开始,这个列表大多数时候应该是空的,除非使用带有非NULL tp_del插槽的C扩展类型的实例。
Cython类不应该在这个无法收集的东西列表中结束,因为它们没有定义tp_del
。
对于早期版本的Python,我认为你也没关系。主要是因为你仍然没有__del__
方法,而且因为cython automatically generates tp_traverse
and tp_clear
functions应该允许Python中断参考周期涉及Cython类。
您可以停用这些tp_traverse
和tp_clear
功能的生成。我有点不清楚参考周期中的对象会发生什么,但没有方法来检测它,或者打破它。它们很可能只是继续存在于某个地方,但却无法进入。
我认为关注(在Python 3.4之前)是__del__
方法可以使对象再次可访问:
class C:
def __del__(self):
global x
x = self
在不返回点之后调用 __dealloc__
,因此不允许这样做(如果访问x
,则只会出现分段错误)。因此,他们不必被gc.garbage
置于不确定的状态。