在Cython 0.25中添加了no_gc
指令。可以找到这个新指令(以及相关的no_gc_clear
指令)的文档here,但我唯一真正理解的是它可以加速你的代码禁用某些方面垃圾收集。
我感兴趣,因为我有一些使用扩展类型的高性能Cython代码,我知道no_gc
可以进一步加快速度。在我的代码中,扩展类型的实例总是处于活动状态,直到程序关闭的最后,这让我觉得禁用垃圾收集可能没问题。
我想我真正需要的是一个例子,其中no_gc
的使用变为错误并导致内存泄漏,同时解释了为什么会发生这种情况。
答案 0 :(得分:1)
与循环引用有关 - 当实例a
持有对再次引用a
的Python对象的引用时,a
永远不会通过引用计数释放,因此Python会尝试检测循环。
可能导致问题的类的一个非常试验示例是:
# Cython code:
cdef class A:
cdef param
def __init__(self):
self.param = self
(以及一些运行它的Python代码)
import cython_module
while True:
cython_module.A()
这很好(检测到周期并且它们经常被解除分配)但是如果你添加no_gc
那么你的内存就会用完。
更现实的例子可能是存储彼此引用的父/子对。
值得补充的是,性能提升可能很小。垃圾收集器仅在分配了大量对象且很少被释放的情况下偶尔运行(https://docs.python.org/3/library/gc.html - 请参阅set_threshold
)。希望这不太可能描述您的高性能代码。
使用GC分配和释放对象时,可能还会产生很小的性能成本,以便在跟踪对象列表中添加/删除它们(但同样,希望您没有分配/取消分配大量数据)
最后,如果你的类从不存储对Python对象的任何引用,那么无论如何它都是有效的no_gc
。设置选项不会有害,但也没有好处。