Python 的可选垃圾收集器 gc
忽略 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__
在不返回点之后调用,因此这是不允许的(如果访问 x
,您只会遇到段错误)。因此,它们不必陷入不确定状态的 gc.garbage
中。
关于python - `gc` 对待 Cython 的 `__dealloc__` 是否与 `__del__` 类似?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46626961/