del*_*del 5 c python garbage-collection memory-leaks
我正在尝试确定 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);
}
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
而且我似乎date在返回的对象列表中根本找不到泄漏的对象gc.get_objects():
>>> from datetime import date
>>> print [obj for obj in gc.get_objects() if isinstance(obj, date)]
[]
Run Code Online (Sandbox Code Playgroud)
我在这里遗漏了一些关于如何gc.get_objects()工作的信息吗?还有另一种方法可以证明 memleak() 函数存在内存泄漏吗?
从模块的文档来看gc:
由于收集器补充了Python 中已使用的引用计数,因此如果您确定您的程序不会创建引用循环,则可以禁用收集器。
因此该gc模块仅用于处理引用循环。在您的情况下,没有循环,因此该函数date不会返回该对象get_objects。
事实上,旧版本的Python根本没有垃圾收集器,它们只使用引用计数。垃圾收集器的引入是为了避免引用循环造成内存泄漏(因为这可以很容易地从 python 端完成,并且您不希望纯 python 程序造成内存泄漏)。
要查看这种内存泄漏,您应该memleak在循环中调用该函数,并查看使用的内存是否增加(在您的情况下缓慢增加)。
还有一些 3rd 方库可用于分析内存使用情况,请参阅推荐使用哪种 Python 内存分析器?关于SO的问题。
| 归档时间: |
|
| 查看次数: |
5359 次 |
| 最近记录: |