Rya*_*heu 6 python memory-management cython
我正在尝试追踪内存泄漏,所以我已经完成了
import tracemalloc
tracemalloc.start()
<function call>
# copy pasted this from documentation
snapshot = tracemalloc.take_snapshot()
top_stats = snapshot.statistics('lineno')
print("[ Top 10 ]")
for stat in top_stats[:10]:
print(stat)
Run Code Online (Sandbox Code Playgroud)
这显示没有主要分配,所有内存分配都非常小,而我看到在psand 中分配了 8+ GB 内存pmap(在运行命令之前和之后以及运行垃圾收集之后进行检查)。此外,tracemalloc.get_traced_memory确认tracemalloc没有看到很多分配。pympler也没有看到分配。
有谁知道什么时候会出现这种情况?某些模块正在使用 cython,这会导致 tracemalloc 出现问题吗?
在 pmap 中,分配看起来像:
0000000002183000 6492008 6491876 6491876 rw--- [ anon ]
从关于tracemalloc的文档:
The tracemalloc module is a debug tool to trace memory blocks allocated by Python.
换句话说,tracemalloc 看不到 python 解释器未分配的内存。这将包括PyMalloc在 C-API 级别未完成的任何事情,包括malloc通过扩展使用的本机代码或malloc直接使用的扩展代码的所有标准 libc调用。
如果没有可重现的代码,就无法确定是否是这种情况。您可以尝试在 python 之外运行本机代码部分,例如通过 valgrind 来检测本机代码中的内存泄漏。
如果有 cython 代码在执行malloc,则可以切换到PyMalloc它以进行跟踪。
对@danny 的答案的补充,因为评论太长了。
如PEP-464中所述,使用PEP-445tracemalloc中引入的功能来跟踪内存分配。
通常,必须使用PyMem_RawMalloc而不是malloc为了能够用于tracemallocC 扩展。然而,由于相当长一段时间也使用pymem.h中的PyTraceMalloc_Track和作为补充(而不是用 替换它)。PyTraceMalloc_UntrackmallocPyMem_RawMalloc
例如,这就是 numpy 中使用的内容,因为为了能够包装原始 c 指针并接管其所有权,使用 numpymalloc而不是 python 分配器,后者针对小对象进行了优化 - 这不是最关键的场景numpy,如下所示:
/*NUMPY_API
* Allocates memory for array data.
*/
NPY_NO_EXPORT void *
PyDataMem_NEW(size_t size)
{
void *result;
result = malloc(size);
if (_PyDataMem_eventhook != NULL) {
NPY_ALLOW_C_API_DEF
NPY_ALLOW_C_API
if (_PyDataMem_eventhook != NULL) {
(*_PyDataMem_eventhook)(NULL, result, size,
_PyDataMem_eventhook_user_data);
}
NPY_DISABLE_C_API
}
PyTraceMalloc_Track(NPY_TRACE_DOMAIN, (npy_uintp)result, size);
return result;
}
Run Code Online (Sandbox Code Playgroud)
因此,基本上,C 扩展有责任向tracemalloc模块报告内存分配,另一方面,tracemalloc不能真正信任其注册所有内存分配。