我正在开发一个C扩展,目前想追踪内存泄漏。通过阅读Python的文档,很难理解何时增加/减少Python对象的引用计数。此外,在尝试嵌入Python解释器(以便将扩展编译为独立程序)的几天中,我不得不放弃这个努力。因此,像Valgrind这样的工具在这里是无助的。
到目前为止,通过反复尝试,我学会了一些东西,例如Py_DECREF(Py_None)
是一件坏事...但是对于任何常量都是这样吗?我不知道。
目前我的主要困惑可以列举如下:
- 如果对象在创建它的过程中没有超出该过程的生存期,那么我是否必须减少由
PyWhatever_New()
创建的任何东西的引用计数? - 每个
Py_INCREF
是否需要与Py_DECREF
匹配,还是应该多一个/另一个? - 如果调用Python过程的结果是
PyObject*
,那么我是否需要增加它以确保我仍然可以使用它(永远),或者减少它以确保最终它将被垃圾回收,还是两者都不需要? - 通过C API创建的Python对象在堆栈上分配还是在堆上分配?(例如,
Py_INCREF
可能会将它们重新分配到堆上)。 - 在将创建的Python对象传递给Python代码之前,我是否需要对C代码中创建的Python对象采取任何特殊措施?如果Python代码的生存期超出了创建Python对象的C代码的生存期怎么办?
- 最后,我知道Python既有引用计数又有垃圾回收器:在这种情况下,如果我弄乱了引用计数(即没有减少足够),那么这对对象有多重要?垃圾回收器最终会找到处理这些对象的方法吗?