减少长时间运行应用程序中的numpy内存占用

Hau*_*uke 7 python garbage-collection memory-management numpy

在我的应用程序中,生成了100个numpy数组(每个1000个复杂元素)并填充了数据.然后经过多次迭代,一遍又一遍地修改数组元素.在初始生成之后,系统监视器报告大约50 Mb的RAM使用情况.虽然我没有生成任何新阵列,但每次迭代的足迹仍然增长了大约40 Mb.

我在这里学到,垃圾收集器不处理numpy数组.所以我假设我正在生成一些操作数据的临时数组没有正确收集.

不幸的是,这里说guppy.hpy().heap()无法帮助分析numpy.

如何识别问题的根源并理想地保持消耗在任何次数的迭代中保持不变?

我怀疑在分配这里描述的数组元素时可能会生成副本,然后不会进行垃圾回收.

我可以手动处理临时numpy数组以协助垃圾回收吗?

[更新1]:示例代码

这段代码被称为数千次.每次,足迹都会增加.我不明白为什么,因为根据我的理解,它只是读取现有数组并操纵其他现有数组.这些切片操作中的任何一个都是无意中做的吗?(对不起行长.我可以简化它,但我可能也会隐藏我的错误.)

for ts in np.arange(numTimeslots):
            for fc in np.arange(numFreqChunks):
                interfencep = np.sum( np.dot(np.dot(self.baseStations[bs].cells[cell].CSI_OFDMA[:,:,fc,ts] ,np.diag(cell.OFDMA_power[:,fc,ts])),self.baseStations[bs].cells[cell].CSI_OFDMA[:,:,fc,ts].conj().T) for bs in self.baseStations for cell in bs.cells if cell != self._cell) 
                noisep = np.eye(self.antennas) * (self.noisePower / numFreqChunks)
                self.OFDMA_interferenceCovar[:,:,fc,ts] = noisep + interfencep
                self.OFDMA_EC[:,:,fc,ts] = (np.dot(np.dot(self.OFDMA_CSI[:,:,fc,ts],linalg.inv(noisep+interfencep)),self.OFDMA_CSI[:,:,fc,ts].conj().T))
                eigs = linalg.eig(self.OFDMA_EC[:,:,fc,ts])[0]
                self.OFDMA_SINR[:,fc,ts] = np.real(eigs)
Run Code Online (Sandbox Code Playgroud)

[更新2]:对于那些好奇的人来说,这是移动网络模拟器的一部分.运行virtualenv,Python 2.7.3,Numpy 1.6.2,SciPy 0.11.0b1

[更新3]:通过评论和检查系统监视器,我可以将'interferencep = ...' - 行识别为罪魁祸首.它分配了大量未释放的内存.但为什么?

Nic*_*bey 5

我遇到了同样的问题.不幸的是我找不到解决方法.唯一对我有用的是将代码重构为小的独立函数.应该制作这些函数,以便我可以说服自己我没有引用数组来阻止垃圾收集器收集数组.你应该特别注意通过切片等生成的数组视图......

为了使代码更高效,更不容易出现内存泄漏,我经常发现使用许多numpy函数提供的out = keyword参数很有用.


Hau*_*uke 2

通过使用系统监视器和代码检查/注释,我发现了内存泄漏。这是由于将 numpy 数组与不同文件中的空列表进行比较引起的。我将在不同的地方深入研究泄漏并投票删除这个问题,因为我发现它太具体而无法帮助其他人。

[更新1]:描述问题根源的新问题: 为什么numpy数组与列表的比较会消耗这么多内存?