`gc` 是否像对待 `__del__` 一样对待 Cython 的 `__dealloc__`?
Does `gc` treat Cython's `__dealloc__` similarly to `__del__`?
Python 的可选垃圾收集器 gc
ignores cycles that contain any object with a __del__
method:
Changed in version 3.4: Following PEP 442, objects with a __del__()
method don’t end up in gc.garbage
anymore.
Cython 扩展类型可以有一个 __dealloc__
方法,但是 no __del__
method:
Note: There is no __del__()
method for extension types.
为了收集循环,垃圾收集器是否将 __dealloc__
的存在视为存在 __del__
方法?或者 __dealloc__
对垃圾收集器不可见?
如果查看生成的 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__
)。
Starting with Python 3.4, this list should be empty most of the time, except when using instances of C extension types with a non-NULL tp_del slot.
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__
在 no return 之后被调用,所以这是不允许的(如果你访问 x
,你只会得到一个段错误)。因此,它们不必陷入 gc.garbage
的不确定状态。
Python 的可选垃圾收集器 gc
ignores cycles that contain any object with a __del__
method:
Changed in version 3.4: Following PEP 442, objects with a
__del__()
method don’t end up ingc.garbage
anymore.
Cython 扩展类型可以有一个 __dealloc__
方法,但是 no __del__
method:
Note: There is no
__del__()
method for extension types.
为了收集循环,垃圾收集器是否将 __dealloc__
的存在视为存在 __del__
方法?或者 __dealloc__
对垃圾收集器不可见?
如果查看生成的 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__
)。
Starting with Python 3.4, this list should be empty most of the time, except when using instances of C extension types with a non-NULL tp_del slot.
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__
在 no return 之后被调用,所以这是不允许的(如果你访问 x
,你只会得到一个段错误)。因此,它们不必陷入 gc.garbage
的不确定状态。