Python Cython指令no_gc的使用

Python Cython指令no_gc的使用,python,garbage-collection,cython,Python,Garbage Collection,Cython,在Cython 0.25中,添加了no\u gc指令。可以找到这个新指令(以及相关的no\u gc\u clear指令)的文档,但我真正了解的是,它可以通过禁用垃圾收集的某些方面来加快代码的速度 我很感兴趣,因为我有一些使用扩展类型的高性能Cython代码,我知道no\u gc可以进一步加快速度。在我的代码中,扩展类型的实例总是保持活动状态,直到程序关闭的最后一刻,这使我认为禁用这些类型的垃圾收集可能是可以的 我想我真正需要的是一个例子,其中no_gc的使用变得糟糕,并导致内存泄漏,这与循环引用

在Cython 0.25中,添加了
no\u gc
指令。可以找到这个新指令(以及相关的
no\u gc\u clear
指令)的文档,但我真正了解的是,它可以通过禁用垃圾收集的某些方面来加快代码的速度

我很感兴趣,因为我有一些使用扩展类型的高性能Cython代码,我知道
no\u gc
可以进一步加快速度。在我的代码中,扩展类型的实例总是保持活动状态,直到程序关闭的最后一刻,这使我认为禁用这些类型的垃圾收集可能是可以的


我想我真正需要的是一个例子,其中
no_gc
的使用变得糟糕,并导致内存泄漏,这与循环引用有关-当实例
a
持有一个对Python对象的引用,该对象再次引用
a
时,
a
将永远无法通过引用计数释放,因此Python尝试检测循环

可能导致问题的类的一个非常典型的例子是:

# Cython code:

cdef class A:
    cdef param

    def __init__(self):
        self.param = self
(还有一些运行它的Python代码)

这是很好的(周期被检测到,并且它们每隔一段时间就会被释放),但是如果您添加
no\u gc
,那么您将耗尽内存

更现实的例子可能是存储相互引用的父/子对


值得补充的是,性能提升可能很小。垃圾收集器仅在分配了大量对象而释放的对象很少的情况下偶尔运行(-请参见
set\u threshold
)。希望这不太可能描述您的高性能代码

在使用GC分配和取消分配对象时,从跟踪对象列表中添加/删除它们可能也会带来较小的性能成本(但是,希望您不会分配/取消分配大量对象)



最后,如果您的类从未存储对Python对象的任何引用,那么它实际上就是
no\u gc
。设置该选项既没有坏处,也没有好处。

如果同时有许多
a
实例处于活动状态,则
no\u gc
可以显著节省内存:gc跟踪支持需要每个对象实例两个指针(16字节内存)的开销。您只需要确保在引用循环中从不涉及
实例。
import cython_module
while True:
    cython_module.A()