Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/325.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python中内存泄漏的单元测试_Python_Memory Leaks_Python C Api - Fatal编程技术网

Python中内存泄漏的单元测试

Python中内存泄漏的单元测试,python,memory-leaks,python-c-api,Python,Memory Leaks,Python C Api,有没有办法在Python中运行内存泄漏单元测试?我已经编写了一些C++绑定代码,并希望确保它不会泄漏内存。 例如,我希望进行如下测试: memory_usage_0 = 0 memory_usage_1 = 0 memory_usage_0 = get_memory_usage() do_cpp_bound_operation() memory_usage_1 = get_memory_usage() assert memory_usage_0 == memory_usage_1 如果您愿意让

有没有办法在Python中运行内存泄漏单元测试?我已经编写了一些C++绑定代码,并希望确保它不会泄漏内存。 例如,我希望进行如下测试:

memory_usage_0 = 0
memory_usage_1 = 0
memory_usage_0 = get_memory_usage()
do_cpp_bound_operation()
memory_usage_1 = get_memory_usage()
assert memory_usage_0 == memory_usage_1

如果您愿意让单元测试变得缓慢,下面是一种基于您的编码示例的尝试方法:

将代码片段更改为如下所示:

gc.collect()
callCppCoreGenerationFunction()
do_cpp_bound_operation()
gc.collect()
callCppCoreGenerationFunction()
compareCores()

你的CalcppPoCeEngEngult函数可以调用一个C或C++函数,它就像一个新进程一样简单,并且让孩子自己杀死,例如,让子引用一个空指针。关键是要做到简单,因为您不希望该函数在核心生成期间执行额外的python分配,从而弄脏了局面

这里要讨论的关键部分是compareCores()。为此,您可以使用分叉进程的标准python代码,因为您已经有了要比较的内核,并且不需要担心结果会失真。例如,您可以使用一个shell脚本来计算您的答案

现在的问题是shell脚本中应该包含什么。它应该做的第一件事是按创建顺序列出核心,以便您可以比较最近的两个。然后在chap中打开每个核心(可从获取的开源软件)。对于每个core,应在chap中打开它,并从chap提示符运行以下命令:

count leaked
这看起来像这样,将捕获泄漏的本机分配对象和一些(但肯定不是全部)泄漏的python对象

chap> count leaked
0 allocations use 0x0 (0) bytes.
该特定命令非常可靠,因为chap旨在避免泄漏的误报。因此,您甚至可以在两个内核中的第二个上运行此操作,而这样的检查根本不需要第一个内核。如果您确实发现泄漏,则可以使用其他chap命令来分析泄漏,但如果您只想知道是否存在此类泄漏,而不想知道原因,那么计数就足够了

describe used
这将描述所有已分配但未释放的分配(python和本机)。它的输出看起来像这样,但有更多的行:

Anchored allocation at 7f505b117630 of size 40
This allocation matches pattern ContainerPythonObject.
This has a PyGC_Head at the start so the real PyObject is at offset 0x10.
This has reference count 1 and python type 0x903f20 (dict)

Anchored allocation at 7f505b117670 of size 40
This allocation matches pattern ContainerPythonObject.
This has a PyGC_Head at the start so the real PyObject is at offset 0x10.
This has reference count 1 and python type 0x8fd660 (list)

Anchored allocation at 16f8a80 of size 238
This allocation matches pattern SimplePythonObject.
This has reference count 1 and python type 0x7f5e824cdfe0 (str)
This has a string of length 512 starting with
"bytearray(iterable_of_ints) -> bytearray
bytearray(string, encoding[, errors]".
在该输出中,%SimplePythonObject”是一些python对象,如不引用其他python对象的str,“%ContainerPythonObject”是可以引用其他python对象的python对象,因此要接受垃圾收集

注意,给出了每个对象的Python引用计数。这意味着,在回答关于检查C++代码是否已经完成引用计数不正确的问题时,这将反映在输出文件中给定对象的引用计数的变化中。因此,错误仅限于单个引用CU。可能导致泄漏的nt错误可以通过这种方式捕获


%SimplePythonObject通常可以被检测为泄漏,只需对一个核心使用“count leaked”,只要没有分配(python或本机或…)仍然引用它,而是使用比较“descripe”的输出“更通用,并为您的用例提供更好的覆盖范围。

您不必担心Python中的内存泄漏,内存是可管理的。我已经创建了一个C扩展,但我想确保引用计数(如中所示)正确。您可以始终在valgrindI下运行脚本。我不太了解valgrindI,但它似乎不容易被做成一个单元测试AFAICT。这可能是真的