在长时间运行的过程中,numpy tolist()存在明显的内存泄漏

时间:2015-12-01 14:11:37

标签: python python-2.7 numpy

我运行一个服务器,作为团队内客户的数据处理节点。最近,我们一直在重构服务器中的遗留代码,以利用 numpy 进行某些过滤/转换作业。

由于我们必须将此数据提供给远程客户端,我们将numpy数据转换为各种形式,使用 numpy.tolist()作为中间步骤。

每个查询都是无状态的,没有全局变量,因此在查询之间不会维护任何引用。

在一个特定的步骤中,我得到明显的内存泄漏,我一直试图通过 memory_profiler 来追踪。该步骤涉及将大的(> 4m条目)ndarray的浮点数转换为python列表。我第一次发出查询时,tolist()调用分配120m内存,然后在释放numpy数组时释放31m。第二个(以及随后的时间)我发出相同的查询,分配/解除分配是31米。我发出的每个不同查询都具有相同的模式,但具有不同的绝对值。

我已经拆开了我的代码,并强制执行一些del命令以用于说明目的。下面的输出来自 memory_profiler.profile

第一期查询:

Line #    Mem usage    Increment   Line Contents
================================================
   865    296.6 MiB      0.0 MiB           p = ikeyData[1]['value']
   866    417.2 MiB    120.6 MiB           newArr = p.tolist()
   867    417.2 MiB      0.0 MiB           del p
   868    385.6 MiB    -31.6 MiB           del ikeyData[1]['value']
   869    385.6 MiB      0.0 MiB           ikeyData[1]['value'] = newArr

同一查询的第二个(及后续)实例:

Line #    Mem usage    Increment   Line Contents
================================================
   865    494.7 MiB      0.0 MiB           p = ikeyData[1]['value']
   866    526.3 MiB     31.6 MiB           newArr = p.tolist()
   867    526.3 MiB      0.0 MiB           del p
   868    494.7 MiB    -31.6 MiB           del ikeyData[1]['value']
   869    494.7 MiB      0.0 MiB           ikeyData[1]['value'] = newArr

可以想象,在长期运行的高可变查询过程中,这些分配会迫使我们定期退回服务器。

有没有人想过这里会发生什么?

1 个答案:

答案 0 :(得分:1)

在你的情况下,Python可能已经释放了内存。

这并不意味着内存分配器必然会返回内存 到操作系统。 memory_profiler使用系统调用来查找当前使用的内存量。所以你的代码可能没什么问题。