我正在尝试确定 Python C 扩展模块中是否存在任何引用计数内存泄漏。考虑这个泄漏date
对象的非常简单的测试扩展:
#include <Python.h>
#include <datetime.h>
static PyObject* memleak(PyObject *self, PyObject *args) {
PyDate_FromDate(2000, 1, 1); /* deliberately create a memory leak */
Py_RETURN_NONE;
}
static PyMethodDef memleak_methods[] = {
{"memleak", memleak, METH_NOARGS, "Leak some memory"},
{NULL, NULL, 0, NULL} /* Sentinel */
};
PyMODINIT_FUNC initmemleak(void) {
PyDateTime_IMPORT;
Py_InitModule("memleak", memleak_methods);
}
PyDate_FromDate 创建一个新的引用(即内部调用 Py_INCREF),因为我从不调用 Py_DECREF,所以这个对象永远不会被垃圾收集。
但是,当我调用此函数时,垃圾收集器跟踪的对象数量在函数调用前后似乎没有变化:
Python 2.7.3 (default, Apr 10 2013, 05:13:16)
[GCC 4.7.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from memleak import memleak
>>> import gc
>>> gc.disable()
>>> gc.collect()
0
>>> len(gc.get_objects()) # get object count before
3581
>>> memleak()
>>> gc.collect()
0
>>> len(gc.get_objects()) # get object count after
3581
而且我似乎根本无法date
在返回的对象列表中找到泄漏的对象gc.get_objects()
:
>>> from datetime import date
>>> print [obj for obj in gc.get_objects() if isinstance(obj, date)]
[]
我在这里遗漏了一些关于如何gc.get_objects()
工作的东西吗?还有其他方法可以证明 memleak() 函数存在内存泄漏吗?